home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / os9 / os9rec.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  9KB  |  250 lines

  1. /*
  2.  * os9rec.c receive file routines for os9 kermit
  3.  */
  4.  
  5. #include "os9inc.h"
  6.  
  7. /*
  8.  * r e c s w
  9.  *
  10.  * This is the state table switcher for receiving files.
  11.  */
  12.  
  13. recsw()
  14. {
  15.         char    rinit(), rfile(), rdata();        /* Use these procedures */
  16.  
  17.         state = 'R';    /* Receive-Init is the start state */
  18.         n = 0;          /* Initialize message number */
  19.         numtry = 0;     /* Say no tries yet */
  20.  
  21. /*
  22.  * We are commenting out code that automatically NAKed
  23.  * in case the sender started first; this may be the reason
  24.  * that this Kermit gets out of whack.  The original code
  25.  * said
  26.  *      if (gflg == FALSE)
  27.  *              spack('N', n, 0, 0);
  28.  */
  29.  
  30.         for (;;) {
  31.                 if (debug)
  32.                         printf(" recsw state: %c\n",state);
  33.                 switch(state) {       /* Do until done */
  34.                 case 'R':   
  35.                         state = rinit(); break; /* Receive-Init */
  36.                 case 'F':   
  37.                         state = rfile(); break; /* Receive-File */
  38.                 case 'D':   
  39.                         state = rdata(); break; /* Receive-Data */
  40.                 case 'C':   
  41.                         return(TRUE);           /* Complete state */
  42.                 case 'A':   
  43.                         return(FALSE);          /* "Abort" state */
  44.                 }
  45.         }
  46. }
  47.  
  48. /*
  49.  *  r i n i t
  50.  *
  51.  *  Receive Initialization
  52.  */
  53.  
  54. char rinit()
  55. {
  56.         int     len, num;       /* Packet length, number */
  57.         char    sfile();        /* routine used for get command */
  58.  
  59.         if (numtry++ > MAXTRY)
  60.                 return('A');    /* If too many tries, "abort" */
  61.  
  62.         switch(rpack(&len, &num, packet)) {  /* Get a packet */
  63.         case 'S':         /* Send-Init */
  64.                 rpar(packet);           /* Get the other side's init data */
  65.                 spar(packet);           /* Fill up packet with my init info */
  66.                 spack('Y', n, 6, packet);   /* ACK with my parameters */
  67.                 oldtry = numtry;        /* Save old try count */
  68.                 numtry = 0;             /* Start a new counter */
  69.                 n = (n + 1) % 64;       /* Bump packet number, mod 64 */
  70.                 return('F');            /* Enter File-Receive state */
  71.  
  72.         case 'E':         /* Error packet received */
  73.                 prerrpkt(packet);      /* Print it out and */
  74.                 return('A');      /* abort */
  75.  
  76.         case FALSE:         /* Didn't get packet */
  77.         case 'N':           /* or got a NAK */
  78.                 if (gflg)
  79.                         sfile();                /* request file again */
  80.                 else
  81.                         spack('N', n, 0, 0);      /* Return a NAK */
  82.                 return(state);      /* Keep trying */
  83.  
  84.         case 'Y':
  85.                 return(state);          /* Ignore leftover ACK */
  86.                 /* (or incorrect ACK of 'R' packet) */
  87.  
  88.         default:     
  89.                 return('A');   /* Some other packet type, "abort" */
  90.         }
  91. }
  92.  
  93. /*
  94.  *  r f i l e
  95.  *
  96.  *  Receive File Header
  97.  */
  98.  
  99. char rfile()
  100. {
  101.         int     num, len;       /* Packet number, length */
  102.         char    filnam1[50];    /* Holds the converted file name */
  103.  
  104.         if (numtry++ > MAXTRY)
  105.                 return('A');    /* "abort" if too many tries */
  106.  
  107.         switch (rpack(&len, &num, packet)) {  /* Get a packet */
  108.         case 'S':         /* Send-Init, maybe our ACK lost */
  109.                 if (oldtry++ > MAXTRY)
  110.                         return('A'); /* If too many tries "abort" */
  111.                 if (num != ((n == 0) ? 63 : n - 1))
  112.                         return('A');      /* Not previous packet, "abort" */
  113.                 /* Previous packet, mod 64; ack with our */
  114.                 /* Send-Init parameters */
  115.                 spar(packet);
  116.                 spack('Y', num, 6, packet);
  117.                 numtry = 0;      /* Reset try counter */
  118.                 return(state);      /* Stay in this state */
  119.  
  120.         case 'Z':         /* End-Of-File */
  121.                 if (oldtry++ > MAXTRY)
  122.                         return('A');
  123.                 if (num != ((n==0) ? 63:n-1))
  124.                         return('A');      /* Not previous packet, "abort" */
  125.                 spack('Y',num,0,0);
  126.                 numtry = 0;
  127.                 return(state);      /* Stay in this state */
  128.  
  129.         case 'F':         /* File Header (just what we want) */
  130.                 if (num != n)
  131.                         return('A');   /* The packet number must be right */
  132.                 strcpy(filnam1, packet);   /* Copy the file name */
  133.  
  134.                 if (filnamcnv) {      /* Convert upper case to lower */
  135.                         for (filnam = filnam1; *filnam != '\0'; filnam++)
  136.                                 if (*filnam >= 'A' && *filnam <= 'Z')
  137.                                         *filnam |= 040;
  138.                 }
  139.  
  140.                 /* Try to open a new file */
  141.  
  142.                 if ((fp = fopen(filnam1, "w")) == NULL)  {
  143.                         error("Cannot create %s", filnam1);
  144.                         return('A');    /* Give up */
  145.                 }
  146.  
  147.                 /* OK, give message */
  148.                 printmsg("Receiving %s as %s", packet, filnam1);
  149.  
  150.                 spack('Y', n, 0, 0);    /* Acknowledge the file header */
  151.                 oldtry = numtry;        /* Reset try counters */
  152.                 numtry = 0;             /* ... */
  153.                 n = (n + 1) % 64;       /* Bump packet number, mod 64 */
  154.                 return('D');            /* Switch to Data state */
  155.  
  156.         case 'B':         /* Break transmission (EOT) */
  157.                 if (num != n)
  158.                         return ('A');   /* Need right packet number here */
  159.                 spack('Y', n, 0, 0);    /* Say OK */
  160.                 return('C');            /* Go to complete state */
  161.  
  162.         case 'E':         /* Error packet received */
  163.                 prerrpkt(packet);       /* Print it out and */
  164.                 return('A');            /* abort */
  165.  
  166.         case FALSE:         /* Didn't get packet */
  167.                 spack('N', n, 0, 0);    /* Return a NAK */
  168.                 return(state);          /* Keep trying */
  169.  
  170.         default:    
  171.                 return ('A');   /* Some other packet, "abort" */
  172.         }
  173. }
  174.  
  175. /*
  176.  *  r d a t a
  177.  *
  178.  *  Receive Data
  179.  */
  180.  
  181. char rdata()
  182. {
  183.         int     num, len;         /* Packet number, length */
  184.  
  185.         if (numtry++ > MAXTRY)
  186.                 return('A'); /* "abort" if too many tries */
  187.  
  188.         switch (rpack(&len, &num, packet)) {   /* Get packet */
  189.         case 'D':         /* Got Data packet */
  190.                 if (num != n) {      /* Right packet? */
  191.                         /* No! */
  192.                         if (oldtry++ > MAXTRY ||        /* too many tries */
  193.                             (num != ((n==0) ? 63:n-1))) /* not prev. packet */
  194.                                 return('A');
  195.                         spack('Y', num, 6, packet);     /* Yes, re-ACK it */
  196.                         numtry = 0;                     /* Reset try counter */
  197.                         return(state);                  /* Don't write data! */
  198.                 }
  199.                 /* Got data with right packet number */
  200. #ifdef nooverlap
  201.                 /* Cannot handle concurrent disk and serial i/o, so delay ACK */
  202.                 /* until file written */
  203.                 bufemp(packet, len);    /* Write the data to the file */
  204.                 spack('Y', n, 0, 0);    /* Acknowledge the packet */
  205. #else
  206.                 /* ACK before file write to overlap disk and serial i/o */
  207.                 spack('Y', n, 0, 0);    /* Acknowledge the packet */
  208.                 bufemp(packet, len);    /* Write the data to the file */
  209. #endif
  210.                 oldtry = numtry;        /* Reset the try counters */
  211.                 numtry = 0;             /* ... */
  212.                 n = (n + 1) % 64;       /* Bump packet number, mod 64 */
  213.                 return('D');            /* Remain in data state */
  214.  
  215.         case 'F':         /* Got a File Header */
  216.                 if (oldtry++ > MAXTRY ||        /* too many tries */
  217.                     (num != ((n==0) ? 63:n-1))) /* not prev. packet */
  218.                         return('A');
  219.                 spack('Y', num, 0, 0);  /* ACK it again */
  220.                 numtry = 0;             /* Reset try counter */
  221.                 return(state);          /* Stay in Data state */
  222.  
  223.         case 'Z':         /* End-Of-File */
  224.                 if (num != n)
  225.                         return('A');   /* Must have right packet number */
  226. #ifdef nooverlap
  227.                 /* can't handle disk and serial i/o at the same time */
  228.                 fclose(fp);             /* close the file */
  229.                 spack('Y', n, 0, 0);    /* Ack the 'Z' packet */
  230. #else
  231.                 /* ACK before close to allow i/o overlap */
  232.                 spack('Y', n, 0, 0);    /* OK, ACK it. */
  233.                 fclose(fp);             /* Close the file */
  234. #endif
  235.                 n = (n + 1) % 64;      /* Bump packet number */
  236.                 return('F');            /* Go back to Receive File state */
  237.  
  238.         case 'E':         /* Error packet received */
  239.                 prerrpkt(packet);      /* Print it out and */
  240.                 return('A');            /* abort */
  241.  
  242.         case FALSE:         /* Didn't get packet */
  243.                 spack('N', n, 0, 0);      /* Return a NAK */
  244.                 return(state);      /* Keep trying */
  245.  
  246.         default:     
  247.                 return('A');   /* Some other packet, "abort" */
  248.         }
  249. }
  250.