home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / telecomm / uemlsrc / kerrec.c < prev    next >
C/C++ Source or Header  |  1987-08-24  |  16KB  |  424 lines

  1. /* kerrec.c kermit protocol file receive support.
  2.  */
  3.  
  4. #include <stdio.h>
  5. #include <osbind.h>
  6. #include "ed.h"
  7. #include "kermit.h"
  8.  
  9. extern char getfiln[NFILEN];
  10.  
  11. /*
  12. *      r e c s w
  13. *
  14. * This is the state table switcher for receiving files.
  15. */
  16.  
  17. recsw()
  18. {
  19.  
  20.         state = 'R';                /* Receive-Init is the start state */
  21.         n = np = 0;                       /* Initialize message number */
  22.         numtry = 0;                  /* Say no tries yet */
  23.  
  24.         while(TRUE)
  25.         {
  26.         switch(state)              /* Do until done */
  27.                 {
  28.                 case 'R':
  29.                         state = rinit();
  30.                         mlwrite("[Awaiting remote init]");
  31.                         break; /* Receive-Init */
  32.                 case 'F':
  33.                         state = rfile();
  34.                         break; /* Receive-File */
  35.                 case 'D':
  36.                         state = rdata();
  37.                         break; /* Receive-Data */
  38.                 case 'C':
  39.                         return(TRUE);      /* Complete state */
  40.                 case 'A':
  41.                         return(FALSE);    /* "Abort" state */
  42.                 }
  43.         }
  44. }
  45.  
  46. /*
  47.  * astget.c server function GET
  48.  * implemented by B. Nebel
  49.  */
  50. getsw()
  51. {
  52.         int result;
  53.  
  54.         flushinput();
  55.         spack('R',0,strlen(getfiln),getfiln);
  56.         result = recsw();
  57.         return (result);
  58. }
  59.  
  60. /*
  61. *      r i n i t
  62. *
  63. * Receive Initialization
  64. */
  65.  
  66. char rinit()
  67. {
  68.         int len, num;              /* Packet length, number */
  69.  
  70.         if (numtry++ > MAXTRY) return('A');     /* If too many tries, "abort" */
  71.  
  72.         switch(rpack(&len,&num,packet))  /* Get a packet */
  73.         {
  74.         case 'S':                      /* Send-Init */
  75.                 rpar(packet,len);       /* Get the other side's init data */
  76.                 len = spar(packet);     /* Fill up packet with my init info */
  77.                 spack('Y',n,len,packet);        /* ACK with my parameters */
  78.                 oldtry = numtry;                /* Save old try count */
  79.                 numtry = 0;                  /* Start a new counter */
  80.                 n = (n+1)%64;      /* Bump packet number, mod 64 */
  81.                 return('F');        /* Enter File-Receive state */
  82.  
  83.         case 'E':                      /* Error packet received */
  84.                 prerrpkt(recpkt);       /* Print it out and */
  85.                 return('A');        /* abort */
  86.  
  87.         case FALSE:                  /* Didn't get packet */
  88.                 spack('N',n,0,NULLPTR);    /* Return a NAK */
  89.                 return(state);    /* Keep trying */
  90.  
  91.         default:
  92.                 return('A');        /* Some other packet type, "abort" */
  93.         }
  94. }
  95.  
  96.  
  97. /*
  98. *      r f i l e
  99. *
  100. * Receive File Header
  101. */
  102.  
  103. char rfile()
  104. {
  105.         int num, len;              /* Packet number, length */
  106.  
  107.         if (numtry++ > MAXTRY) return('A');     /* "abort" if too many tries */
  108.  
  109.         switch(rpack(&len,&num,packet))  /* Get a packet */
  110.         {
  111.         case 'S':                      /* Send-Init, maybe our ACK lost */
  112.                 /* If too many tries "abort" */
  113.                 if (oldtry++ > MAXTRY) return('A');
  114.                 if (num == ((n==0) ? 63:n-1)) /* Previous packet, mod 64? */
  115.                 {                              /* Yes, ACK it again with */
  116.                         len = spar(packet);     /* our Send-Init parameters */
  117.                         spack('Y',num,len,packet);
  118.                         numtry = 0;          /* Reset try counter */
  119.                         return(state);    /* Stay in this state */
  120.                 }
  121.                 else return('A');       /* Not previous packet, "abort" */
  122.  
  123.         case 'Z':                      /* End-Of-File */
  124.                 if (oldtry++ > MAXTRY) return('A');
  125.                 if (num == ((n==0) ? 63:n-1)) /* Previous packet, mod 64? */
  126.                 {                              /* Yes, ACK it again. */
  127.                         spack('Y',num,0,NULLPTR);
  128.                         numtry = 0;
  129.                         return(state);    /* Stay in this state */
  130.                 }
  131.                 else return('A');       /* Not previous packet, "abort" */
  132.  
  133.         case 'F':                      /* File Header (just what we want) */
  134.                 /* The packet number must be right */
  135.                 if (num != n) return('A');
  136.                 mlwrite("[Receiving %s as %s]",packet,curbp->b_bname);
  137.  
  138.                 spack('Y',n,0,NULLPTR);    /* Acknowledge the file header */
  139.                 oldtry = numtry;        /* Reset try counters */
  140.                 numtry = 0;
  141.                 n = (n+1)%64;      /* Bump packet number, mod 64 */
  142.                 return('D');        /* Switch to Data state */
  143.  
  144.         case 'B':                      /* Break transmission (EOT) */
  145.                 if (num != n) return ('A'); /* Need right packet number here */
  146.                 spack('Y',n,0,NULLPTR);     /* Say OK */
  147.                 return('C');        /* Go to complete state */
  148.  
  149.         case 'E':                      /* Error packet received */
  150.                 prerrpkt(recpkt);       /* Print it out and */
  151.                 return('A');        /* abort */
  152.  
  153.         case FALSE:                  /* Didn't get packet */
  154.                 spack('N',n,0,NULLPTR);    /* Return a NAK */
  155.                 return(state);    /* Keep trying */
  156.  
  157.         default:
  158.                 return ('A');      /* Some other packet, "abort" */
  159.         }
  160. }
  161.  
  162.  
  163. /*
  164. *      r d a t a
  165. *
  166. * Receive Data
  167. */
  168.  
  169. char rdata()
  170. {
  171.         int num, len;              /* Packet number, length */
  172.         if (numtry++ > MAXTRY) return('A');     /* "abort" if too many tries */
  173.  
  174.         switch(rpack(&len,&num,packet))  /* Get packet */
  175.         {
  176.         case 'D':                      /* Got Data packet */
  177.                 if (num != n)      /* Right packet? */
  178.                 {                              /* No */
  179.                         if (oldtry++ > MAXTRY)
  180.                                 return('A');    /* If too many tries, abort */
  181.                         if (num == ((n==0) ? 63:n-1))
  182.                         { /* Else check previous packet again? */
  183.                                 spack('Y',num,0,NULLPTR); /* Yes, re-ACK it */
  184.                                 numtry = 0;     /* Reset try counter */
  185.                                 return(state);  /* Don't write out data! */
  186.                         }
  187.                         else return('A');       /* sorry, wrong number */
  188.                 }
  189.                 /* Got data with right packet number */
  190.                 bufemp(packet,len);          /* Write the data to the file */
  191.                 spack('Y',n,0,NULLPTR);     /* Acknowledge the packet */
  192.                 oldtry = numtry;                /* Reset the try counters */
  193.                 numtry = 0;                  /* ... */
  194.                 mlwrite("[Receiving packet: %d]", ++np);
  195.                 n = (n+1)%64;      /* Bump packet number, mod 64 */
  196.                 return('D');        /* Remain in data state */
  197.  
  198.         case 'F':                      /* Got a File Header */
  199.                 if (oldtry++ > MAXTRY)
  200.                         return('A');        /* If too many tries, "abort" */
  201.                 if (num == ((n==0) ? 63:n-1))   /* Else check packet number */
  202.                 {                              /* It was the previous one */
  203.                         spack('Y',num,0,NULLPTR);  /* ACK it again */
  204.                         numtry = 0;          /* Reset try counter */
  205.                         return(state);    /* Stay in Data state */
  206.                 }
  207.                 else return('A');       /* Not previous packet, "abort" */
  208.  
  209.         case 'Z':                      /* End-Of-File */
  210.                 /* Must have right packet number */
  211.                 if (num != n) return('A');
  212.                 spack('Y',n,0,NULLPTR);     /* OK, ACK it. */
  213.                 n = (n+1)%64;      /* Bump packet number */
  214.                 return('F');        /* Go back to Receive File state */
  215.  
  216.         case 'E':                      /* Error packet received */
  217.                 prerrpkt(recpkt);              /* Print it out and */
  218.                 return('A');        /* abort */
  219.  
  220.         case FALSE:                  /* Didn't get packet */
  221.                 spack('N',n,0,NULLPTR);     /* Return a NAK */
  222.                 return(state);    /* Keep trying */
  223.  
  224.         default:
  225.                 return('A');        /* Some other packet, "abort" */
  226.         }
  227. }
  228.  
  229. /*
  230. *      r p a c k
  231. *
  232. * Read a Packet
  233. */
  234.  
  235. char
  236. rpack(len,num,data)
  237. int *len, *num;                  /* Packet length, number */
  238. char *data;                          /* Packet data */
  239. {
  240.         register int i, done;       /* Data character number, loop exit */
  241.         register char t,         /* Current input character */
  242.         cchksum,                /* Our (computed) checksum */
  243.         rchksum,                        /* Checksum received from other host */
  244.         type;              /* Packet type */
  245.  
  246.         do
  247.         {
  248.                 if (Bconstat(2))
  249.                         if (ttgetc() == 0x07) /* ^G abort */
  250.                                 {
  251.                                 mlwrite("User ABORT");
  252.                                 (*term.t_beep)();
  253.                                 return('A');
  254.                                 }
  255.                 if (!Cauxis())
  256.                         continue;
  257.                 else
  258.                         t = (char)readaux()& 0x7f;
  259.         }while (t != SOH);                    /* Wait for packet header */
  260.  
  261.         done = FALSE;              /* Got SOH, init loop */
  262.         while (!done)              /* Loop to get a packet */
  263.         {
  264.                 if (Bconstat(2))
  265.                         if (ttgetc() == 0x07) /* ^G abort */
  266.                                 {
  267.                                 mlwrite("User ABORT");
  268.                                 (*term.t_beep)();
  269.                                 return('A');
  270.                                 }
  271.                 t = (char)readaux();        /* Get character */
  272.                 if (t == SOH) continue;  /* Resynchronize if SOH */
  273.                 cchksum = t;                /* Start the checksum */
  274.                 *len = unchar(t)-3;          /* Character count */
  275.  
  276.                 t = (char)readaux();        /* Get character */
  277.                 if (t == SOH) continue;  /* Resynchronize if SOH */
  278.                 cchksum += t;              /* Update checksum */
  279.                 *num = unchar(t);              /* Packet number */
  280.  
  281.                 t = (char)readaux();        /* Get character */
  282.                 if (t == SOH) continue;  /* Resynchronize if SOH */
  283.                 cchksum += t;              /* Update checksum */
  284.                 type = t;                      /* Packet type */
  285.  
  286.                 for (i=0; i<*len; i++)    /* The data itself, if any */
  287.                 {                              /* Loop for character count */
  288.                         if (Bconstat(2))
  289.                                 if (ttgetc() == 0x07) /* ^G abort */
  290.                                         {
  291.                                         mlwrite("User ABORT");
  292.                                         (*term.t_beep)();
  293.                                         return('A');
  294.                                         }
  295.                         t = (char)readaux();    /* Get character */
  296.                         if (t == SOH) continue; /* Resynch if SOH */
  297.                         cchksum += t;      /* Update checksum */
  298.                         data[i] = t;        /* Put it in the data buffer */
  299.                 }
  300.                 data[*len] = 0;          /* Mark the end of the data */
  301.  
  302.                 t = (char)readaux();        /* Get last character (checksum) */
  303.                 rchksum = unchar(t);        /* Convert to numeric */
  304.                 t = (char)readaux();       /* get EOL character and toss it */
  305.                 if (t == SOH) continue;  /* Resynchronize if SOH */
  306.                 done = TRUE;                /* Got checksum, done */
  307.         }
  308.         /* Fold in bits 7,8 to compute */
  309.         cchksum = (((cchksum&0300) >> 6)+cchksum)&077; /* final checksum */
  310.  
  311.         if (cchksum != rchksum) return((char)FALSE);
  312.         return(type);              /* All OK, return packet type */
  313. }
  314.  
  315. /*      r p a r
  316. *
  317. * Get the other host's send-init parameters
  318. *
  319. */
  320.  
  321. void
  322. rpar(data,len)
  323. char data[];
  324. int len;
  325. {
  326.         spsiz = DEFMAXL;        /* default packet size */
  327.         timint = DEFTIME;
  328.         pad = DEFPAD;
  329.         padchar = DEFPADC;
  330.         eol = DEFEOL;
  331.         quotech = DEFQUOTE;
  332.         qbin = DEFQBIN;
  333.         switch (len){
  334.         default:
  335.         case 10:        /* attributes */
  336.         case 9:         /* repeat count */
  337.         case 8:         /* Check type */
  338.         case 7:         /* 8 bit quoting */
  339.                 qbin = data[6];
  340.                 if (((qbin >='!') && (qbin <= '>'))
  341.                     || ((qbin >= '`')&&(qbin <= '~')))
  342.                      /*   qflag = TRUE; */ en8quote(TRUE);     /* jgc dec 25th.
  343. 1985 */
  344.         case 6:         /* Incoming data quote character */
  345.                 quotech = data[5];
  346.         case 5:         /* EOL character I must send */
  347.                 eol = unchar(data[4]);
  348.         case 4:         /* Padding character I must send */
  349.                 padchar = ctl(data[3]);
  350.         case 3:         /* Number of pads to send */
  351.                 pad = unchar(data[2]);
  352.         case 2:         /* When I should time out */
  353.                 timint = unchar(data[1]);
  354.                 if ((timint > MAXTIM) || (timint < MINTIM)) timint = MYTIME;
  355.         case 1:         /* Maximum send packet size */
  356.                 spsiz = unchar(data[0]);
  357.         case 0:
  358.                 break;
  359.         }
  360.         if (qflag) {
  361.                 if (qbin == 'N') mlwrite("Can't do 8 bit quoting");
  362.                 else if (qbin == 'Y') qbin = QBIN;
  363.         }
  364. }
  365.  
  366. /*
  367. *      s p a r
  368. *
  369. * Fill the data array with my send-init parameters
  370. *
  371. */
  372.  
  373. int
  374. spar(data)
  375. char data[];
  376. {
  377.         data[0] = tochar(MYPACKSIZ);    /* Biggest packet I can receive */
  378.         data[1] = tochar(MYTIME);       /* When I want to be timed out */
  379.         data[2] = tochar(MYPAD);        /* How much padding I need */
  380.         data[3] = ctl(MYPCHAR);  /* Padding character I want */
  381.         data[4] = tochar(MYEOL);        /* End-Of-Line character I want */
  382.         data[5] = MYQUOTE;            /* Control-Quote character I send */
  383.         data[6] = qflag?QBIN:'Y';       /* Request 8 bit quoting */
  384.         return (7);                  /* return number of parameters */
  385. }
  386.  
  387. /*
  388. *      s p a c k
  389. *
  390. * Send a Packet
  391. */
  392.  
  393. void
  394. spack(type,num,len,data)
  395. char type, *data;
  396. int num, len;
  397. {
  398.         register int i;                   /* Character loop counter */
  399.         char chksum, buffer[100];       /* Checksum, packet buffer */
  400.         register char *bufp;        /* Buffer pointer */
  401.  
  402.  
  403.         bufp = buffer;            /* Set up buffer pointer */
  404.         for (i=1; i<=pad; i++) sendaux(padchar); /* Issue any padding */
  405.  
  406.         *bufp++ = SOH;            /* Packet marker, ASCII 1 (SOH) */
  407.         *bufp++ = tochar(len+3);        /* Send the character count */
  408.         chksum = tochar(len+3);  /* Initialize the checksum */
  409.         *bufp++ = tochar(num);    /* Packet number */
  410.         chksum += tochar(num);    /* Update checksum */
  411.         *bufp++ = type;          /* Packet type */
  412.         chksum += type;          /* Update checksum */
  413.  
  414.         for (i=0; i<len; i++)      /* Loop for all data characters */
  415.         {
  416.                 *bufp++ = data[i];            /* Get a character */
  417.                 chksum += data[i];            /* Update checksum */
  418.         }
  419.         chksum = (((chksum&0300) >> 6)+chksum)&077; /* Compute final checksum */
  420.         *bufp++ = tochar(chksum);       /* Put it in the packet */
  421.         *bufp = eol;                /* Extra-packet line terminator */
  422.         sauxstr( buffer,((int)bufp-(int)buffer+1)); /* Send the packet */
  423. }
  424.