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

  1. /*
  2.  * os9sen.c  send file routines of os9 kermit
  3.  */
  4.  
  5. #include "os9inc.h"
  6.  
  7. /*
  8.  *  s e n d s w
  9.  *
  10.  *  Sendsw is the state table switcher for sending files.  It loops until
  11.  *  either it finishes, or an error is encountered.  The routines called
  12.  *  by sendsw are responsible for changing the state.
  13.  *
  14.  */
  15.  
  16. sendsw()
  17. {
  18.         char sinit(), sfile(), sdata(), seof(), sbreak();
  19.  
  20.         state = 'S';    /* Send initiate is the start state */
  21.         n = 0;          /* Initialize message number */
  22.         numtry = 0;     /* Say no tries yet */
  23.         for (;;) {      /* Do this as long as necessary */
  24.                 if (debug)
  25.                         printf("sendsw state: %c, Packet # %d\n",state,n);
  26.                 if ((!remot) && (!debug)) 
  27.                         if (n % 10 == 0)
  28.                                 printmsg("Status: Sending Packet # %d",n);
  29.  
  30.                 switch(state) {
  31.                 case 'S':
  32.                         state = sinit(); break; /* Send-Init */
  33.                 case 'F':
  34.                         state = sfile(); break; /* Send-File */
  35.                 case 'D':
  36.                         state = sdata(); break; /* Send-Data */
  37.                 case 'Z':
  38.                         state = seof(); break;  /* Send-End-of-File */
  39.                 case 'B':
  40.                         state = sbreak(); break;/* Send-Break */
  41.                 case 'C':   
  42.                         return (TRUE);          /* Complete */
  43.                 case 'A':   
  44.                         return (FALSE);         /* "Abort" */
  45.                 default:   
  46.                         return (FALSE);         /* Unknown, fail */
  47.                 }
  48.         }
  49. }
  50.  
  51. /*
  52.  *  s i n i t
  53.  *
  54.  *  Send Initiate: send this host's parameters and get other side's back.
  55.  */
  56.  
  57. char sinit()
  58. {
  59.         int num, len;           /* Packet number, length */
  60.  
  61.         if (numtry++ > MAXTRY)
  62.                 return('A');    /* If too many tries, give up */
  63.         spar(packet);           /* Fill up init info packet */
  64.  
  65.         flushinput();           /* Flush pending input */
  66.  
  67.         spack('S', n, 6, packet);      /* Send an S packet */
  68.         switch(rpack(&len, &num, recpkt)) {  /* What was the reply? */
  69.         case 'N':  
  70.                 return(state);   /* NAK, try it again */
  71.  
  72.         case 'Y':         /* ACK */
  73.                 if (n != num)      /* If wrong ACK, stay in S state */
  74.                         return(state);      /* and try again */
  75.                 rpar(recpkt);      /* Get other side's init info */
  76.  
  77.                 if (eol == 0) eol = '\n';   /* Check and set defaults */
  78.                 if (quote == 0) quote = '#';
  79.  
  80.                 numtry = 0;             /* Reset try counter */
  81.                 n = (n + 1) % 64;       /* Bump packet count */
  82.                 return('F');            /* OK, switch state to F */
  83.  
  84.         case 'E':         /* Error packet received */
  85.                 prerrpkt(recpkt);       /* Print it out and */
  86.                 return('A');            /* abort */
  87.  
  88.         case FALSE: 
  89.                 return(state);          /* Receive failure, try again */
  90.  
  91.         default: 
  92.                 return('A');            /* Anything else, just "abort" */
  93.         }
  94. }
  95.  
  96. /*
  97.  *  s f i l e
  98.  *
  99.  *  Send File Header.
  100.  */
  101.  
  102. char sfile()
  103. {
  104.         int     num, len;       /* Packet number, length */
  105.         char    filnam1[50],    /* Converted file name */
  106.                 *newfilnam,     /* Pointer to file name to send */
  107.                 *cp;            /* char pointer */
  108.  
  109.         if (numtry++ > MAXTRY)
  110.                 return('A');    /* If too many tries, give up */
  111.  
  112.         if (gflg == 0) {          /* If Get mode just send name  */
  113.                 if (fp == NULL) {        /* If not already open, */
  114.                         if (debug)
  115.                                 printf("   Opening %s for sending.\n",filnam);
  116.                         /* open the file to be sent */
  117.                         fp = fopen(filnam,"r");
  118.                         if (fp == NULL) {
  119.                                 /* bad file pointer, give up */
  120.                                 error("Cannot open file %s",filnam);
  121.                                 return('A');
  122.                         }
  123.                 }
  124.         }
  125.  
  126.         strcpy(filnam1, filnam);      /* Copy file name */
  127.         newfilnam = cp = filnam1;
  128.         if (!gflg)                    /* if not in get routine */
  129.                 while (*cp != '\0')   /* Strip off all leading directory */
  130.                         if (*cp++ == '/')   /* names (ie. up to the last /). */
  131.                                 newfilnam = cp;
  132.  
  133.         if (filnamcnv)                /* Convert lower case to upper   */
  134.                 for (cp = newfilnam; *cp != '\0'; cp++)
  135.                         if (*cp >= 'a' && *cp <= 'z')
  136.                                 *cp ^= 040;
  137.  
  138.         len = cp - newfilnam;      /* Compute length of new filename */
  139.  
  140.         if (gflg == 0) {     /*  If not Get function   */
  141.                 printmsg("Sending %s as %s", filnam, newfilnam);
  142.                 spack('F', n, len, newfilnam);   /* Send an F packet */
  143.         } else {
  144.                 spack('R', n, len, newfilnam);   /* Send Get file packet */
  145.                 return('R');
  146.         }
  147.  
  148.         switch(rpack(&len, &num, recpkt)) {       /* What was the reply? */
  149.         case 'N':                         /* NAK, just stay in this state, */
  150.                 num = (--num<0 ? 63:num); /* unless it's NAK for next packet */
  151.                 if (n != num)             /* which is just like an ACK for */ 
  152.                         return(state);    /* this packet so fall thru to... */
  153.  
  154.         case 'Y':                       /* ACK */
  155.                 if (gflg != 0)          /* Test if get function  */
  156.                         return('D');    /* If so no number check, Done */
  157.                 if (n != num)
  158.                         return(state);  /* If wrong ACK, stay in F state */
  159.                 numtry = 0;             /* Reset try counter */
  160.                 n = (n + 1) % 64;       /* Bump packet count */
  161.                 size = bufill(packet);  /* Get first data from file */
  162.                 return('D');            /* Switch state to D */
  163.  
  164.         case 'E':                       /* Error packet received */
  165.                 prerrpkt(recpkt);       /* Print it out and */
  166.                 return('A');            /* abort */
  167.  
  168.         case FALSE:
  169.                 return(state);          /* Receive failure, stay in F state */
  170.  
  171.         default: 
  172.                 return('A');            /* Something else, just "abort" */
  173.         }
  174. }
  175.  
  176. /*
  177.  *  s d a t a
  178.  *
  179.  *  Send File Data
  180.  */
  181.  
  182. char sdata()
  183. {
  184.         int     num, len;         /* Packet number, length */
  185.  
  186.         if (numtry++ > MAXTRY)
  187.                 return('A'); /* If too many tries, give up */
  188.  
  189.         spack('D', n, size, packet);      /* Send a D packet */
  190.         switch (rpack(&len, &num, recpkt)) {   /* What was the reply? */
  191.         case 'N':         /* NAK, just stay in this state, */
  192.                 num = (--num<0 ? 63:num);   /* unless it's next packet's NAK */
  193.                 if (n != num)               /* which is just like an ACK for */
  194.                         return(state);      /* this packet so fall thru to... */
  195.  
  196.         case 'Y':         /* ACK */
  197.                 if (n != num)
  198.                         return(state);  /* If wrong ACK, fail */
  199.                 numtry = 0;             /* Reset try counter */
  200.                 n = (n+1)%64;           /* Bump packet count */
  201.                 if ((size = bufill(packet)) == EOF) /* Get data from file */
  202.                         return('Z');    /* If EOF set state to that */
  203.                 return('D');            /* Got data, stay in state D */
  204.  
  205.         case 'E':         /* Error packet received */
  206.                 prerrpkt(recpkt);       /* Print it out and */
  207.                 return('A');            /* abort */
  208.  
  209.         case FALSE: 
  210.                 return(state);   /* Receive failure, stay in D */
  211.  
  212.         default:    
  213.                 return('A');   /* Anything else, "abort" */
  214.         }
  215. }
  216.  
  217. /*
  218.  *  s e o f
  219.  *
  220.  *  Send End-Of-File.
  221.  */
  222.  
  223. char
  224. seof()
  225. {
  226.         int     num, len;         /* Packet number, length */
  227.  
  228.         if (numtry++ > MAXTRY)
  229.                 return('A'); /* If too many tries, "abort" */
  230.  
  231.         spack('Z', n, 0, packet);      /* Send a 'Z' packet */
  232.         switch(rpack(&len, &num, recpkt)) {   /* What was the reply? */
  233.         case 'N':         /* NAK, just stay in this state, */
  234.                 num = (--num<0 ? 63:num);   /* unless it's next packet's NAK, */
  235.                 if (n != num)               /* which is just like an ACK for */
  236.                         return(state);      /* this packet so fall thru to... */
  237.  
  238.         case 'Y':         /* ACK */
  239.                 if (n != num)
  240.                         return(state);  /* If wrong ACK, hold out */
  241.                 numtry = 0;             /* Reset try counter */
  242.                 n = (n+1)%64;           /* and bump packet count */
  243.                 if (debug)
  244.                         printf("     Closing input file %s, ",filnam);
  245.                 fclose(fp);             /* Close the input file */
  246.                 fp = NULL;              /* Set flag indicating no file open */
  247.  
  248.  
  249.                 if (debug)
  250.                         printf("looking for next file...\n");
  251.                 if (gnxtfl() == FALSE)  /* No more files go? */
  252.                         return('B');    /* if not, break, EOT, all done */
  253.                 if (debug)
  254.                         printf("     New file is %s\n",filnam);
  255.                 return('F');            /* More files, switch state to F */
  256.  
  257.         case 'E':         /* Error packet received */
  258.                 prerrpkt(recpkt);       /* Print it out and */
  259.                 return('A');            /* abort */
  260.  
  261.         case FALSE: 
  262.                 return(state);          /* Receive failure, stay in Z */
  263.  
  264.         default:    
  265.                 return('A');            /* Something else, "abort" */
  266.         }
  267. }
  268.  
  269. /*
  270.  *  s b r e a k
  271.  *
  272.  *  Send Break (EOT)
  273.  */
  274.  
  275. char sbreak()
  276. {
  277.         int     num, len;         /* Packet number, length */
  278.  
  279.         if (numtry++ > MAXTRY)
  280.                 return('A'); /* If too many tries "abort" */
  281.  
  282.         spack('B', n, 0, packet);      /* Send a B packet */
  283.         switch (rpack(&len, &num, recpkt)) {  /* What was the reply? */
  284.         case 'N':
  285.                 /* NAK, just stay in this state, */
  286.                 num = (--num<0 ? 63:num);   /* unless previous packet's NAK, */
  287.                 if (n != num)               /* which is just like an ACK for */
  288.                         return(state);      /* this packet so fall thru to... */
  289.  
  290.         case 'Y':         /* ACK */
  291.                 if (n != num)
  292.                         return(state);  /* If wrong ACK, fail */
  293.                 numtry = 0;             /* Reset try counter */
  294.                 n = (n+1)%64;           /* and bump packet count */
  295.                 return('C');            /* Switch state to Complete */
  296.  
  297.         case 'E':         /* Error packet received */
  298.                 prerrpkt(recpkt);       /* Print it out and */
  299.                 return('A');            /* abort */
  300.  
  301.         case FALSE: 
  302.                 return(state);          /* Receive failure, stay in B */
  303.  
  304.         default:    
  305.                 return ('A');           /* Other, "abort" */
  306.         }
  307. }
  308.