home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / atarist / astrec.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  14KB  |  361 lines

  1. /*
  2.  * astrec.c receive file routines for ATARI ST kermit
  3.  */
  4.  
  5. #include <osbind.h>
  6. #include <stdio.h>
  7. #include "astobj.h"
  8. #include "astinc.h"
  9.  
  10. extern FILE *fopen(),*fopenb();
  11.  
  12. /*
  13.  * r e c s w
  14.  *
  15.  * This is the state table switcher for receiving files.
  16.  */
  17.  
  18. recsw()
  19. {
  20.         char    rinit(), rfile(), rdata();        /* Use these procedures */
  21.         start_timer(&starttrans);
  22.         state = 'R';
  23.         n = 0;          /* Initialize message number */
  24.         numtry = 0;     /* Say no tries yet */
  25.  
  26. /*
  27.  * We are commenting out code that automatically NAKed
  28.  * in case the sender started first; this may be the reason
  29.  * that this Kermit gets out of whack.  The original code
  30.  * said
  31.  *      if (gflg == FALSE)
  32.  *              spack('N', n, 0, NIL);
  33.  */
  34.  
  35.         for (;;) {
  36.                 msgdeb(MSGDSTAT,state,n);
  37.                 bps = ((timer(starttrans) != 0) ?
  38.                          (bytecnt/timer(starttrans)) : 0);
  39.                 dt_packets(TRUE);
  40.                 switch(state) {       /* Do until done */
  41.                 case 'R':
  42.                         state = rinit(); break; /* Receive-Init */
  43.                 case 'F':
  44.                         state = rfile(); break; /* Receive-File */
  45.                 case 'D':
  46.                         state = rdata(); break; /* Receive-Data */
  47.                 case 'C':
  48.                         return(TRUE);           /* Complete state */
  49.                 case 'A':
  50.                         spack('E', n, 5, "Abort");
  51.                         return (FALSE);         /* "Abort" */
  52.                 case 'E':
  53.                         return(FALSE);          /* "Error Abort" */
  54.                 default:
  55.                         msgdeb(MSGSTATE);
  56.                         return (FALSE);         /* Unknown, fail */
  57.                 }
  58.         }
  59. }
  60.  
  61. /*
  62.  *  r i n i t
  63.  *
  64.  *  Receive Initialization
  65.  */
  66.  
  67. char rinit()
  68. {
  69.         int     i, len, num;    /* Packet length, number */
  70.         char    sfile();        /* routine used for get command */
  71.  
  72.         if (numtry++ > maxtry)
  73.            {msgall(KRTRAERR,MSGTRAER); return('A');};
  74.  
  75.         ebq = TRUE;                     /* assume 7-bit transfer for init */
  76.         switch(rpack(&len, &num, packet)) {  /* Get a packet */
  77.         case 'S':         /* Send-Init */
  78.                 for (i=len;i<10;i++) packet[i] = '\0';
  79.                 rpar(packet);           /* Get the other side's init data */
  80.                 spar(packet);           /* Fill up packet with my init info */
  81.                 spack('Y', n, 7, packet);   /* ACK with my parameters */
  82.                 oldtry = numtry;        /* Save old try count */
  83.                 numtry = 0;             /* Start a new counter */
  84.                 n = (n + 1) % 64;       /* Bump packet number, mod 64 */
  85.                 n_total++;
  86.                 return('F');            /* Enter File-Receive state */
  87.  
  88.         case 'E':         /* Error packet received */
  89.                 prerrpkt(packet);      /* Print it out and */
  90.                 return('E');      /* abort */
  91.  
  92.         case FALSE:         /* Didn't get packet */
  93.         case 'N':           /* or got a NAK */
  94.                 nakcnt++;
  95.                 if (!getfile)
  96.                     spack('N', n, 0, NIL);  /* Return a NAK */
  97.                 else
  98.                     spack('R',n,strlen(filnam1),filnam1);
  99.                 return(state);      /* Keep trying */
  100.  
  101.         case 'Y':
  102.                 return(state);          /* Ignore leftover ACK */
  103.                 /* (or incorrect ACK of 'R' packet) */
  104.  
  105.         case 'A':
  106.                 return('A');            /* user abort */
  107.  
  108.         default:
  109.                 msgall(KRPROERR,MSGPROER);
  110.                 return('A');   /* Some other packet type, "abort" */
  111.         }
  112. }
  113.  
  114. /*
  115.  *  r f i l e
  116.  *
  117.  *  Receive File Header
  118.  */
  119.  
  120. char rfile()
  121. {
  122.         int     num, len;       /* Packet number, length */
  123.         int     f1x, fx;        /* index to filnam1 and filnam */
  124.         int     extx;           /* start of extension */
  125.         int     tryix;          /* trying numbers for extension */
  126.         char    convc;          /* converted char in filename */
  127.  
  128.         if (numtry++ > maxtry)
  129.            {msgall(KRTRAERR,MSGTRAER); return('A');};
  130.  
  131.         switch (rpack(&len, &num, packet)) {  /* Get a packet */
  132.         case 'S':         /* Send-Init, maybe our ACK lost */
  133.                 nakcnt++;
  134.                 if (oldtry++ > maxtry)
  135.                    {msgall(KRTRAERR,MSGTRAER); return('A');};
  136.                 if (num != ((n == 0) ? 63 : n - 1))
  137.                        {msgall(KRPROERR,MSGPROER);
  138.                         return('A');      /* Not previous packet, "abort" */
  139.                        };
  140.                 /* Previous packet, mod 64; ack with our */
  141.                 /* Send-Init parameters */
  142.                 spar(packet);
  143.                 spack('Y', num, 7, packet);
  144.                 numtry = 0;      /* Reset try counter */
  145.                 return(state);      /* Stay in this state */
  146.  
  147.         case 'Z':         /* End-Of-File */
  148.                 nakcnt++;
  149.                 if (oldtry++ > maxtry)
  150.                    {msgall(KRTRAERR,MSGTRAER); return('A');};
  151.                 if (num != ((n==0) ? 63:n-1))
  152.                        {msgall(KRPROERR,MSGPROER);
  153.                         return('A');      /* Not previous packet, "abort" */
  154.                        };
  155.                 spack('Y',num,0,NIL);
  156.                 numtry = 0;
  157.                 return(state);      /* Stay in this state */
  158.  
  159.         case 'F':         /* File Header (just what we want) */
  160.                 if (num != n)
  161.                        {msgall(KRPROERR,MSGPROER);
  162.                         return('A');   /* The packet number must be right */
  163.                        };
  164.                 strcpy(filnam1, packet);   /* Copy the file name */
  165.  
  166.                 /* convert filename to valid TOS file name*/
  167.                 fx = 0;
  168.                 extx = -1;
  169.                 if (filnam[0] == '\0')
  170.                    {for (f1x = 0; filnam1[f1x] != '\0'; f1x++)
  171.                         {convc = filnam1[f1x];
  172.                         if ((convc >= 'a') && (convc <= 'z'))
  173.                            convc ^= 040;
  174.                         if (convc == ' ')
  175.                            convc = '.';
  176.                         if (!((convc == '.') ||
  177.                               ((convc >= 'A') && (convc <= 'Z')) ||
  178.                               ((convc >= '0') && (convc <= '9'))))
  179.                            convc = ']';
  180.                         if (convc == '.')
  181.                            if (extx >= 0)
  182.                               convc = ']';
  183.                            else
  184.                               extx = fx;
  185.                         if ((fx < 8) ||
  186.                             ((extx >= 0) &&
  187.                             ((fx - extx) < 4)))
  188.                            filnam[fx++] = convc;
  189.                         };
  190.                     filnam[fx] = '\0';
  191.                     if (filnamwarn)
  192.                        {tryix = 0;
  193.                         while ((!access(filnam,4)) && (tryix < 50))
  194.                               {msgdeb(MSGERSNA,filnam1,filnam);
  195.                                if (extx < 0)
  196.                                   {extx = fx;
  197.                                    filnam[fx++] = '.';
  198.                                    filnam[fx] = '\0';
  199.                                   };
  200.                                sprintf(&filnam[extx+1],"K%02d",tryix++);
  201.                                };
  202.                        };
  203.                     };
  204.  
  205.                 /* Try to open a new file */
  206.  
  207.                 if (image)
  208.                    fp = fopenb(filnam,"w");
  209.                 else
  210.                    fp = fopen(filnam,"w");
  211.                 if (fp == NULL)  {
  212.                         msgall(KRWOPERR,MSGWOPER, filnam);
  213.                         return('A');    /* Give up */
  214.                 }
  215.  
  216.                 /* OK, give message */
  217.                 msgall(-1,MSGFRASF, filnam1, filnam);
  218.                 dt_files(TRUE);
  219.                 spack('Y', n, 0, NIL);    /* Acknowledge the file header */
  220.                 n_total++;
  221.                 oldtry = numtry;        /* Reset try counters */
  222.                 numtry = 0;             /* ... */
  223.                 n = (n + 1) % 64;       /* Bump packet number, mod 64 */
  224.                 return('D');            /* Switch to Data state */
  225.  
  226.         case 'B':         /* Break transmission (EOT) */
  227.                 if (num != n)
  228.                        {msgall(KRPROERR,MSGPROER);
  229.                         return ('A');   /* Need right packet number here */
  230.                        };
  231.                 spack('Y', n, 0, NIL);    /* Say OK */
  232.                 n_total++;
  233.                 return('C');            /* Go to complete state */
  234.  
  235.         case 'E':         /* Error packet received */
  236.                 prerrpkt(packet);       /* Print it out and */
  237.                 return('E');            /* abort */
  238.  
  239.         case FALSE:         /* Didn't get packet */
  240.                 spack('N', n, 0, NIL);    /* Return a NAK */
  241.                 nakcnt++;
  242.                 return(state);          /* Keep trying */
  243.  
  244.         case 'A':
  245.                 return('A');            /* user abort */
  246.  
  247.         default:
  248.                 msgall(KRPROERR,MSGPROER);
  249.                 return ('A');   /* Some other packet, "abort" */
  250.         }
  251. }
  252.  
  253. /*
  254.  *  r d a t a
  255.  *
  256.  *  Receive Data
  257.  */
  258.  
  259. char rdata()
  260. {
  261.         int     num, len;         /* Packet number, length */
  262.  
  263.         if (numtry++ > maxtry)
  264.            {msgall(KRTRAERR,MSGTRAER); return('A');};
  265.  
  266.         switch (rpack(&len, &num, packet)) {   /* Get packet */
  267.         case 'D':         /* Got Data packet */
  268.                 if (num != n) {      /* Right packet? */
  269.                         /* No! */
  270.                          if (num != ((n==0) ? 63:n-1)) /* not prev. packet */
  271.                                {msgall(KRPROERR,MSGPROER);
  272.                                 return('A');
  273.                                };
  274.                          if (oldtry++ > maxtry)
  275.                                {msgall(KRTRAERR,MSGTRAER);
  276.                                 return('A');
  277.                                };
  278.                         spack('Y', num, 0, NIL);     /* Yes, re-ACK it */
  279.                         nakcnt++;
  280.                         numtry = 0;                     /* Reset try counter */
  281.                         return(state);                  /* Don't write data! */
  282.                 }
  283.                 /* Got data with right packet number */
  284. #ifdef nooverlap
  285.                 /* Cannot handle concurrent disk and serial i/o, so delay ACK */
  286.                 /* until file written */
  287.                 bufemp(packet, len);    /* Write the data to the file */
  288.                 spack('Y', n, 0, NIL);    /* Acknowledge the packet */
  289. #else
  290.                 /* ACK before file write to overlap disk and serial i/o */
  291.                 spack('Y', n, 0, NIL);    /* Acknowledge the packet */
  292.                 bufemp(packet, len);    /* Write the data to the file */
  293. #endif
  294.                 oldtry = numtry;        /* Reset the try counters */
  295.                 numtry = 0;             /* ... */
  296.                 n = (n + 1) % 64;       /* Bump packet number, mod 64 */
  297.                 n_total++;
  298.                 if (ferror(fp))
  299.                    {msgall(KRFATFER,MSGFATFE);
  300.                     return('A');
  301.                    };
  302.                 return('D');            /* Remain in data state */
  303.  
  304.         case 'F':         /* Got a File Header */
  305.                 if (num != ((n==0) ? 63:n-1)) /* not prev. packet */
  306.                        {msgall(KRPROERR,MSGPROER);
  307.                         return('A');
  308.                        };
  309.                 if (oldtry++ > maxtry)
  310.                        {msgall(KRTRAERR,MSGTRAER);
  311.                         return('A');
  312.                        };
  313.                 spack('Y', num, 0, NIL);  /* ACK it again */
  314.                 nakcnt++;
  315.                 numtry = 0;             /* Reset try counter */
  316.                 return(state);          /* Stay in Data state */
  317.  
  318.         case 'Z':         /* End-Of-File */
  319.                 if (num != n)
  320.                        {msgall(KRPROERR,MSGPROER);
  321.                         return('A');   /* Must have right packet number */
  322.                        };
  323.                 if (ferror(fp))
  324.                    {msgall(KRFATFER,MSGFATFE);
  325.                     return('A');
  326.                    };
  327. #ifdef nooverlap
  328.                 /* can't handle disk and serial i/o at the same time */
  329.                 fclose(fp);             /* close the file */
  330.                 spack('Y', n, 0, NIL);    /* Ack the 'Z' packet */
  331. #else
  332.                 /* ACK before close to allow i/o overlap */
  333.                 spack('Y', n, 0, NIL);    /* OK, ACK it. */
  334.                 fclose(fp);             /* Close the file */
  335. #endif
  336.                 n = (n + 1) % 64;      /* Bump packet number */
  337.                 msgall(-1,MSGTREOF,filnam);
  338.                 n_total++;
  339.                 filecnt++;
  340.                 dt_files(TRUE);
  341.                 filnam[0] = '\0';
  342.                 return('F');            /* Go back to Receive File state */
  343.  
  344.         case 'E':         /* Error packet received */
  345.                 prerrpkt(packet);      /* Print it out and */
  346.                 return('E');            /* abort */
  347.  
  348.         case FALSE:         /* Didn't get packet */
  349.                 spack('N', n, 0, NIL);      /* Return a NAK */
  350.                 nakcnt++;
  351.                 return(state);      /* Keep trying */
  352.  
  353.         case 'A':
  354.                 return('A');            /* user abort */
  355.  
  356.         default:
  357.                 msgall(KRPROERR,MSGPROER);
  358.                 return('A');   /* Some other packet, "abort" */
  359.         }
  360. }
  361.