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

  1. /*
  2.  * astsen.c  send file routines of 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.  *  s e n d s w
  14.  *
  15.  *  Sendsw is the state table switcher for sending files.  It loops until
  16.  *  either it finishes, or an error is encountered.  The routines called
  17.  *  by sendsw are responsible for changing the state.
  18.  *
  19.  */
  20.  
  21.  
  22. sendsw()
  23. {
  24.         char sinit(), sfile(), sdata(), seof(), sbreak();
  25.  
  26.         start_timer(&starttrans);
  27.         state = 'S';    /* Send initiate is the start state */
  28.         n = 0;          /* Initialize message number */
  29.         numtry = 0;     /* Say no tries yet */
  30.         for (;;) {      /* Do this as long as necessary */
  31.                 msgdeb(MSGDSTAT,state,n);
  32.                 bps = ((timer(starttrans) != 0) ?
  33.                          (bytecnt/timer(starttrans)) : 0);
  34.                 dt_packets(TRUE);
  35.                 switch(state) {
  36.                 case 'S':
  37.                         state = sinit(); break; /* Send-Init */
  38.                 case 'F':
  39.                         state = sfile(); break; /* Send-File */
  40.                 case 'D':
  41.                         state = sdata(); break; /* Send-Data */
  42.                 case 'Z':
  43.                         state = seof(); break;  /* Send-End-of-File */
  44.                 case 'B':
  45.                         state = sbreak(); break;/* Send-Break */
  46.                 case 'C':
  47.                         return (TRUE);          /* Complete */
  48.                 case 'A':
  49.                         spack('E', n, 5, "Abort"); /* error packet */
  50.                         return (FALSE);            /* "Abort" */
  51.                 case 'E':
  52.                         return(FALSE);          /* "Error Abort" */
  53.                 default:
  54.                         msgdeb(MSGSTATE);
  55.                         return (FALSE);         /* Unknown, fail */
  56.                 }
  57.         }
  58. }
  59.  
  60. /*
  61.  *  s i n i t
  62.  *
  63.  *  Send Initiate: send this host's parameters and get other side's back.
  64.  */
  65.  
  66. char sinit()
  67. {
  68.         int num, len;           /* Packet number, length */
  69.         int i;
  70.         if (numtry++ > maxtry)
  71.            {msgall(KRTRAERR,MSGTRAER); return('A');};
  72.         ebq = TRUE;             /* assume 7 bit transfer for init */
  73.         spar(packet);           /* Fill up init info packet */
  74.  
  75.         flushinput();           /* Flush pending input */
  76.  
  77.         spack('S', n, 7, packet);      /* Send an S packet */
  78.         for (i = 0; i <= 10; i++) recpkt[i] = 0;
  79.         switch(rpack(&len, &num, recpkt)) {  /* What was the reply? */
  80.         case 'N':
  81.                 nakcnt ++;
  82.                 return(state);   /* NAK, try it again */
  83.  
  84.         case 'Y':         /* ACK */
  85.                 if (n != num)      /* If wrong ACK, stay in S state */
  86.                     {
  87.                      nakcnt++;
  88.                      return(state);      /* and try again */
  89.                     };
  90.                 n_total++;
  91.                 rpar(recpkt);      /* Get other side's init info */
  92.  
  93.                 numtry = 0;             /* Reset try counter */
  94.                 n = (n + 1) % 64;       /* Bump packet count */
  95.                 return('F');            /* OK, switch state to F */
  96.  
  97.         case 'E':         /* Error packet received */
  98.                 prerrpkt(recpkt);       /* Print it out and */
  99.                 return('E');            /* abort */
  100.  
  101.         case FALSE:
  102.                 nakcnt++;
  103.                 return(state);          /* Receive failure, try again */
  104.  
  105.         case 'A':
  106.                 return('A');            /* user abort */
  107.  
  108.         default:
  109.                 msgall(KRPROERR,MSGPROER);
  110.                 return('A');            /* Anything else, just "abort" */
  111.         }
  112. }
  113.  
  114. /*
  115.  *  s f i l e
  116.  *
  117.  *  Send File Header.
  118.  */
  119.  
  120. char sfile()
  121. {
  122.         int     num, len;       /* Packet number, length */
  123.         char    *newfilnam,     /* Pointer to file name to send */
  124.                 *cp;            /* char pointer */
  125.  
  126.         if (numtry++ > maxtry)
  127.            {msgall(KRTRAERR,MSGTRAER);return('A');};
  128.         if (fp == NULL)
  129.             {                /* If not already open, */
  130.              filnam1[0] = '\0';
  131.              dt_files(TRUE);
  132.              msgdeb(MSGFOPN,filnam);
  133.              /* open the file to be sent */
  134.              if (image)
  135.                 fp = fopenb(filnam,"r");
  136.              else
  137.                 fp = fopen(filnam,"r");
  138.              if (fp == NULL)
  139.                 {           /* bad file pointer, give up */
  140.                  msgall(KERRFOPN,MSGERRFO);
  141.                  return('A');
  142.                 };
  143.             };
  144.         strcpy(filnam1, filnam);      /* Copy file name */
  145.         newfilnam = cp = filnam1;
  146.  
  147.         len = strlen(filnam1);        /* Compute length of new filename */
  148.  
  149.         spack('F', n, len, newfilnam);   /* Send an F packet */
  150.  
  151.         switch(rpack(&len, &num, recpkt)) {       /* What was the reply? */
  152.         case 'N':                         /* NAK, just stay in this state, */
  153.                 num = (--num<0 ? 63:num); /* unless it's NAK for next packet */
  154.                 if (n != num)             /* which is just like an ACK for */
  155.                    {nakcnt++;return(state);};
  156.  
  157.         case 'Y':                       /* ACK */
  158.                 if (n != num)
  159.                     {
  160.                      nakcnt++;
  161.                      return(state);      /* and try again */
  162.                     };
  163.                 msgall(-1,MSGSFASF,filnam, newfilnam);
  164.                 dt_files(TRUE);
  165.                 n_total++;
  166.                 numtry = 0;             /* Reset try counter */
  167.                 n = (n + 1) % 64;       /* Bump packet count */
  168.                 size = bufill(packet);  /* Get first data from file */
  169.                 return('D');            /* Switch state to D */
  170.  
  171.         case 'E':                       /* Error packet received */
  172.                 prerrpkt(recpkt);       /* Print it out and */
  173.                 return('E');            /* abort */
  174.  
  175.         case FALSE:
  176.                 nakcnt++;
  177.                 return(state);          /* Receive failure, stay in F state */
  178.  
  179.         case 'A':
  180.                 return('A');            /* user abort */
  181.  
  182.         default:
  183.                 msgall(KRPROERR,MSGPROER);
  184.                 return('A');            /* Something else, just "abort" */
  185.         }
  186. }
  187.  
  188. /*
  189.  *  s d a t a
  190.  *
  191.  *  Send File Data
  192.  */
  193.  
  194. char sdata()
  195. {
  196.         int     num, len;         /* Packet number, length */
  197.  
  198.         if (numtry++ > maxtry)
  199.            {msgall(KRTRAERR,MSGTRAER);return('A');};
  200.  
  201.         spack('D', n, size, packet);      /* Send a D packet */
  202.         switch (rpack(&len, &num, recpkt)) {   /* What was the reply? */
  203.         case 'N':         /* NAK, just stay in this state, */
  204.                 num = (--num<0 ? 63:num);   /* unless it's next packet's NAK */
  205.                 if (n != num)               /* which is just like an ACK for */
  206.                     {
  207.                      nakcnt++;
  208.                      return(state);      /* and try again */
  209.                     };
  210.         case 'Y':         /* ACK */
  211.                 if (n != num)
  212.                     {
  213.                      nakcnt++;
  214.                      return(state);      /* and try again */
  215.                     };
  216.                 n_total++;
  217.                 numtry = 0;             /* Reset try counter */
  218.                 n = (n+1)%64;           /* Bump packet count */
  219.                 if ((size = bufill(packet)) == EOF) /* Get data from file */
  220.                         return('Z');    /* If EOF set state to that */
  221.                 if (ferror(fp))
  222.                    {msgall(KRFATFER,MSGFATFE);
  223.                     return('A');
  224.                    };
  225.                 return('D');            /* Got data, stay in state D */
  226.  
  227.         case 'E':         /* Error packet received */
  228.                 prerrpkt(recpkt);       /* Print it out and */
  229.                 return('E');            /* abort */
  230.  
  231.         case FALSE:
  232.                 nakcnt++;
  233.                 return(state);   /* Receive failure, stay in D */
  234.  
  235.         case 'A':
  236.                 return('A');            /* user abort */
  237.  
  238.         default:
  239.                 msgall(KRPROERR,MSGPROER);
  240.                 return('A');   /* Anything else, "abort" */
  241.         }
  242. }
  243.  
  244. /*
  245.  *  s e o f
  246.  *
  247.  *  Send End-Of-File.
  248.  */
  249.  
  250. char
  251. seof()
  252. {
  253.         int     num, len;         /* Packet number, length */
  254.  
  255.         if (numtry++ > maxtry)
  256.            {msgall(KRTRAERR,MSGTRAER);return('A');};
  257.  
  258.         spack('Z', n, 0, packet);      /* Send a 'Z' packet */
  259.         switch(rpack(&len, &num, recpkt)) {   /* What was the reply? */
  260.         case 'N':         /* NAK, just stay in this state, */
  261.                 num = (--num<0 ? 63:num);   /* unless it's next packet's NAK, */
  262.                 if (n != num)               /* which is just like an ACK for */
  263.                     {
  264.                      nakcnt++;
  265.                      return(state);      /* and try again */
  266.                     };
  267.  
  268.         case 'Y':         /* ACK */
  269.                 if (n != num)
  270.                     {
  271.                      nakcnt++;
  272.                      return(state);      /* and try again */
  273.                     };
  274.                 n_total++;
  275.                 filecnt++;
  276.                 numtry = 0;             /* Reset try counter */
  277.                 n = (n+1)%64;           /* and bump packet count */
  278.                 msgall(-1,MSGTREOF,filnam);
  279.                 fclose(fp);             /* Close the input file */
  280.                 fp = NULL;              /* Set flag indicating no file open */
  281.  
  282.                 msgdeb(MSGFNEXT);
  283.                 if (fnxtfil() == FALSE)  /* No more files go? */
  284.                         return('B');    /* if not, break, EOT, all done */
  285.                 msgdeb(MSGNEWFI,filnam);
  286.                 return('F');            /* More files, switch state to F */
  287.  
  288.         case 'E':         /* Error packet received */
  289.                 prerrpkt(recpkt);       /* Print it out and */
  290.                 return('E');            /* abort */
  291.  
  292.         case FALSE:
  293.                 nakcnt++;
  294.                 return(state);          /* Receive failure, stay in Z */
  295.  
  296.         case 'A':
  297.                 return('A');            /* user abort */
  298.  
  299.         default:
  300.                 msgall(KRPROERR,MSGPROER);
  301.                 return('A');            /* Something else, "abort" */
  302.         }
  303. }
  304.  
  305. /*
  306.  *  s b r e a k
  307.  *
  308.  *  Send Break (EOT)
  309.  */
  310.  
  311. char sbreak()
  312. {
  313.         int     num, len;         /* Packet number, length */
  314.  
  315.         if (numtry++ > maxtry)
  316.            {msgall(KRTRAERR,MSGTRAER);return('A');};
  317.  
  318.         spack('B', n, 0, packet);      /* Send a B packet */
  319.         switch (rpack(&len, &num, recpkt)) {  /* What was the reply? */
  320.         case 'N':
  321.                 /* NAK, just stay in this state, */
  322.                 num = (--num<0 ? 63:num);   /* unless previous packet's NAK, */
  323.                 if (n != num)               /* which is just like an ACK for */
  324.                     {
  325.                      nakcnt++;
  326.                      return(state);      /* and try again */
  327.                     };
  328.  
  329.         case 'Y':         /* ACK */
  330.                 if (n != num)
  331.                     {
  332.                      nakcnt++;
  333.                      return(state);      /* and try again */
  334.                     };
  335.                 n_total++;
  336.                 numtry = 0;             /* Reset try counter */
  337.                 n = (n+1)%64;           /* and bump packet count */
  338.                 return('C');            /* Switch state to Complete */
  339.  
  340.         case 'E':         /* Error packet received */
  341.                 prerrpkt(recpkt);       /* Print it out and */
  342.                 return('E');            /* abort */
  343.  
  344.         case FALSE:
  345.                 nakcnt++;
  346.                 return(state);          /* Receive failure, stay in B */
  347.  
  348.         case 'A':
  349.                 return('A');            /* user abort */
  350.  
  351.         default:
  352.                 msgall(KRPROERR,MSGPROER);
  353.                 return ('A');           /* Other, "abort" */
  354.         }
  355. }
  356.