home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / win100b / wkkerm.c < prev    next >
C/C++ Source or Header  |  1991-10-19  |  15KB  |  501 lines

  1.  
  2. /* WARNING -- This C source program generated by Wart preprocessor. */
  3. /* Do not edit this file; edit the Wart-format source file instead, */
  4. /* and then run it through Wart to produce a new C source file.     */
  5.  
  6. /* Wart Version Info: */
  7. char *wartv = "Wart Version 1A(006) Jan 1989";
  8.  
  9. /*
  10.  * Protocol module for Windows Kermit
  11.  * 
  12.  * Copyright (c) 1990, 1991 by
  13.  * William S. Hall
  14.  * 3665 Benton Street  #66
  15.  * Santa Clara, CA 95051
  16.  *
  17.  * This module must be preprocessed by wart
  18.  */
  19.  
  20. #define NOCOMM
  21. #define NOKANJI
  22. #define NOSOUND
  23. #define NOATOM
  24. #include <windows.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #ifdef COLUMBIA
  28. #include "wkkerm.h"
  29. #else
  30. #include "wnkerm.h"
  31. #endif
  32.  
  33. /* The state machine returns 0 to show completion or 1 if more input
  34.  * is expected.  Currently, these return values are not used.
  35.  */
  36. #define RESUME return(0)
  37. #define CONTINUE return(1)
  38.  
  39. /* local function prototypes */
  40. static int near input(void);
  41.  
  42. static char vcmd;
  43. static int vstate;
  44.  
  45. /* protocol states */
  46. #define get 1
  47. #define rsfile 2
  48. #define rsdata 3
  49. #define ipkt 4
  50. #define rgen 5
  51. #define ssinit 6
  52. #define ssfile 7
  53. #define ssdata 8
  54. #define sseof 9
  55. #define sseot 10
  56.  
  57. /* Protocol description.
  58.  */
  59.  
  60. #define BEGIN state =
  61.  
  62. int state = 0;
  63.  
  64. wart()
  65. {
  66.     int c,actno;
  67.     extern short tbl[];
  68.     while (1) {
  69.     c = input();
  70.     if ((actno = tbl[c + state*128]) != -1)
  71.         switch(actno) {
  72. case 1:
  73.     {        
  74.     krm_tinit();            /* initialize */
  75.     Kermit.start = 'w';            /* switch to wait */
  76. }
  77.     break;
  78. case 2:
  79.     {
  80.     krm_tinit();
  81.     vstate = get;
  82.     vcmd = 0;
  83.     krm_sinit('I');
  84.     BEGIN ipkt;
  85. }
  86.     break;
  87. case 3:
  88.     {
  89.     krm_tinit();
  90.     vstate = rgen;
  91.     vcmd = 'C';
  92.     krm_sinit('I');
  93.     BEGIN ipkt;
  94. }
  95.     break;
  96. case 4:
  97.     {
  98.     krm_tinit();
  99.     vstate = rgen;
  100.     vcmd = 'G';
  101.     krm_sinit('I');
  102.     BEGIN ipkt;
  103. }
  104.     break;
  105. case 5:
  106.     {
  107.     if (Kermit.delay) {            /* timer will reset this parameter */
  108.     Kermit.start = 'w';        /* wait to send first packet */
  109.         CONTINUE;
  110.     } else {
  111.         if (krm_sinit('S') < 0) {        /* transmit sendinit packet */
  112.             krm_err(IDS_KRM_SENDINIT_ERROR);    /* error; inform remote */
  113.             RESUME;                /* quit */
  114.         }    
  115.     krmFlushQue();        /* flush any pending input in local buffer */
  116.         BEGIN ssinit;        /* prepare to open file and send file name */
  117.     }    
  118. }
  119.     break;
  120. case 6:
  121.     {
  122.     krm_tinit();            /* initialize */
  123.     BEGIN get;
  124. }
  125.     break;
  126. case 7:
  127.     {
  128.     krm_spar(krm_rcvpkt.data, krm_rcvpkt.len);    /* read send-init data */
  129.     if (vcmd) {
  130.         if (krm_sendcmd(vcmd, Kermit.pFilelist) < 0) {
  131.             krm_err(IDS_KRM_SENDCMD_ERROR);    /* error; inform remote */
  132.             RESUME;                /* quit */
  133.         }    
  134.     vcmd = 0;
  135.     }
  136.     if (vstate == get)
  137.         if (krm_srinit(Kermit.pFilelist) < 0) {
  138.         krm_err(IDS_KRM_SENDR_ERROR);
  139.         RESUME;
  140.     }
  141.     BEGIN vstate;
  142. }
  143.     break;
  144. case 8:
  145.     {
  146.     if (vcmd)
  147.         if (krm_sendcmd(vcmd, Kermit.pFilelist) < 0) {
  148.             krm_err(IDS_KRM_SENDCMD_ERROR);    /* error; inform remote */
  149.             RESUME;                /* quit */
  150.         }    
  151.     vcmd = 0;
  152.     if (vstate == get)
  153.         if (krm_srinit(Kermit.pFilelist) < 0) {
  154.         krm_err(IDS_KRM_SENDR_ERROR);
  155.         RESUME;
  156.     }
  157.     BEGIN vstate;
  158. }
  159.     break;
  160. case 9:
  161.     {
  162.     krm_spar(krm_rcvpkt.data, krm_rcvpkt.len);    /* set init data */
  163.     Kermit.bctu = Kermit.bctr;            /* select block check type */
  164.     Kermit.pFile = krm_getnextfile(TRUE);    /* get file to send */
  165.     if (krm_sfile() < 0) {            /* send file name packet */
  166.         krm_err(IDS_KRM_SENDFILENAME_ERROR);    /* error; inform remote */
  167.         RESUME;                    /* quit */
  168.     }
  169.     BEGIN ssfile;               /* prepare to send first data packet */
  170. }
  171.     break;
  172. case 10:
  173.     {
  174.     int x;
  175.     krm_savename();            /* post the remote's name for file */
  176.     if ((x = krm_sdata()) == 0) {    /* no data in file */
  177.         if (krm_seof("") < 0) {        /* send end of file */
  178.            krm_err(IDS_KRM_SENDEOF_ERROR);   /* error; inform remote */
  179.            RESUME;            /* quit */
  180.         }
  181.         BEGIN sseof;
  182.     }
  183.     else if (x < 0) {            /* error in sending file */
  184.         krm_rclose(FALSE);        /* close the file */
  185.         krm_err(IDS_KRM_SENDDATA_ERROR); /* post error to remote and quit */
  186.         RESUME;
  187.     }
  188.     else
  189.     BEGIN ssdata;            /* prepare to receive data */
  190. }
  191.     break;
  192. case 11:
  193.     {                
  194.     krm_checkcnx();            /* check if transaction cancelled */
  195.     if (Kermit.abort) {
  196.     if (Kermit.abort == KRM_FILEABORT)  /* cancel file send */
  197.         Kermit.abort = 0;
  198.     if (krm_seof("D") < 0) {        /* tell remote about cancellation */
  199.        krm_err(IDS_KRM_SENDEOF_ERROR);  /* error; inform remote */
  200.        RESUME;                /* quit */
  201.     }
  202.         BEGIN sseof;            /* prepare to send end of file */
  203.     }
  204.     else {
  205.         int x;
  206.     if ((x = krm_sdata()) == 0) {        /* no more data */
  207.         if (krm_seof("") < 0) {        /* send end of file */
  208.            krm_err(IDS_KRM_SENDEOF_ERROR);  /* error; inform remote */
  209.            RESUME;                /* quit */
  210.         }
  211.             BEGIN sseof;        /* prepare to send end of file */
  212.         }
  213.     else if (x < 0) {            /* error */
  214.         krm_rclose(FALSE);            /* close the file */
  215.         krm_err(IDS_KRM_SENDDATA_ERROR);    /* inform remote */
  216.         RESUME;                /* quit */
  217.         }
  218.     }
  219. }
  220.     break;
  221. case 12:
  222.     {
  223.     if (Kermit.pFile = krm_getnextfile(FALSE)) {  /* any more files? */
  224.         if (krm_sfile() < 0) {              /* send next file name */
  225.             krm_err(IDS_KRM_SENDFILENAME_ERROR);  /* error, inform remote */
  226.             RESUME;                  /* quit */
  227.         }
  228.         BEGIN ssfile;                /* prepare for next file */
  229.     }    
  230.     else {                    /* no more files to send */
  231.     if (krm_seot() < 0) {            /* send break */
  232.         krm_err(IDS_KRM_SENDEOT_ERROR);    /* error, inform remote */
  233.         RESUME;                /* quit */
  234.     }
  235.     BEGIN sseot;                /* prepare to exit file send */
  236.     }
  237. }
  238.     break;
  239. case 13:
  240.     {
  241.     krm_tend(IDS_KRM_TRANSACTION_DONE);        /* clean up */
  242.     RESUME;                    /* quit */
  243. }
  244.     break;
  245. case 14:
  246.     {
  247.  
  248.     krm_srinit(Kermit.pFilelist);
  249.  
  250. }
  251.     break;
  252. case 15:
  253.     {
  254.     if (krm_rcvpkt.len > 0)
  255.     krm_tend(KRM_DATA_PACKET);
  256.     else
  257.         krm_tend(IDS_KRM_TRANSACTION_DONE);    /* clean up */
  258.     RESUME;                    /* quit */
  259. }
  260.     break;
  261. case 16:
  262.     {
  263.     BYTE data[KRM_MAXDATALEN + 1];
  264.     krm_spar(krm_rcvpkt.data, krm_rcvpkt.len);    /* read send-init data */
  265.     krm_ack(krm_rpar(data), data);        /* return init data in ACK */
  266.     Kermit.bctu = Kermit.bctr;            /* set block check type */
  267.     BEGIN rsfile;                    /* prepare for file name */
  268. }
  269.     break;
  270. case 17:
  271.     {
  272.     if (krm_rcvfil()) {                /* try to open file */
  273.     char buf[KRM_MAXDATALEN + 1];            
  274.     int inlen, outlen;
  275.     inlen = strlen(Kermit.pFile);        /* return our name to remote */
  276.     outlen = krm_encode(buf, Kermit.pFile, sizeof(buf) - 1, &inlen);
  277.         krm_ack(outlen, buf);            /* send the name in ACK */
  278.         BEGIN rsdata;                /* prepare to receive data */
  279.     }
  280.     else {
  281.     krm_err(IDS_KRM_FILE_OPEN_ERROR);    /* error, inform remote */
  282.     RESUME;                    /* quit */
  283.     }
  284. }
  285.     break;
  286. case 18:
  287.     {
  288.     if (krm_opent()) {
  289.     krm_ack(0, "");
  290.     BEGIN rsdata;
  291.     }
  292.     else {
  293.     krm_err(IDS_KRM_TERMINAL_OPEN_ERROR);
  294.     RESUME;
  295.     }
  296. }
  297.     break;
  298. case 19:
  299.     {
  300.     if (krm_rcvdata()) {
  301.     switch(Kermit.abort) {            /* see if abort flag is on */
  302.         case KRM_BATCHABORT:
  303.         krm_ack(1, "Z");        /* cancel remaining files */
  304.         Kermit.abort = 0;
  305.         break;
  306.         case KRM_FILEABORT:
  307.         krm_ack(1, "X");        /* cancel current file */
  308.         Kermit.abort = 0;
  309.         break;
  310.         default:
  311.         krm_ack(0, "");                /* continue */
  312.     }
  313.     }
  314.     else {
  315.     krm_rclose(TRUE);            /* error in storing data */
  316.     krm_err(IDS_KRM_FILE_WRITE_ERROR);    /* inform host */
  317.     RESUME;                    /* quit */
  318.     }
  319. }
  320.     break;
  321. case 20:
  322.     {        /* see if remote wants us to delete file */
  323.     if (krm_rclose(krm_rcvpkt.len && 
  324.     (krm_rcvpkt.data[0] == 'D') ? TRUE : FALSE)) {
  325.         krm_ack(0, "");                /* acknowledge */
  326.         BEGIN rsfile;                /* prepare for next file */
  327.     }
  328.     else {
  329.     krm_err(IDS_KRM_FILE_CLOSE_ERROR);    /* error; inform remote */
  330.     RESUME;                    /* quit */
  331.     }
  332. }
  333.     break;
  334. case 21:
  335.     {
  336.     krm_ack(0, "");            /* acknowledge */
  337.     krm_tend(IDS_KRM_TRANSACTION_DONE);    /* clean up */
  338.     RESUME;                /* quit */
  339. }
  340.     break;
  341. case 22:
  342.     {
  343.     CONTINUE;            /* continue until packet is filled */
  344. }
  345.     break;
  346. case 23:
  347.     {
  348.     krm_rclose(TRUE);        /* close any open files */
  349.     krm_tend(KRM_DATA_PACKET);    /* clean up */
  350.     RESUME;            /* quit */
  351. }
  352.     break;
  353. case 24:
  354.     {
  355.     krm_rclose(TRUE);            /* close any open files */
  356.     krm_err(IDS_KRM_UNKNOWN_PACKET);    /* post error to remote */
  357.     RESUME;                /* quit */
  358. }
  359.     break;
  360.  
  361.         }
  362.     }
  363. }
  364.  
  365. short tbl[] = {
  366. -1, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  367. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  368. 24, 24, 24, 24, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  369. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  370. 24, 24, 24, 24, 24, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  371. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  372. 24, 24, 24,  3, 24, 24, 24,  4, 24, 24, 24, 24, 24, 24, 24, 24, 
  373. 24, 24,  2,  1, 24, 24,  6,  5, 24, 24, 24, 24, 24, 24, 24, 24, 
  374. -1, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  375. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  376. 24, 24, 24, 24, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  377. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  378. 24, 24, 24, 24, 24, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  379. 24, 24, 24, 16, 24, 24, 24, 24, 24, 14, 24, 24, 24, 24, 24, 24, 
  380. 24, 24, 24,  3, 24, 24, 24,  4, 24, 24, 24, 24, 24, 24, 24, 24, 
  381. 24, 24,  2,  1, 24, 24,  6,  5, 24, 24, 24, 24, 24, 24, 24, 24, 
  382. -1, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  383. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  384. 24, 24, 24, 24, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  385. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  386. 24, 24, 21, 24, 24, 23, 17, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  387. 24, 24, 24, 24, 24, 24, 24, 24, 18, 24, 24, 24, 24, 24, 24, 24, 
  388. 24, 24, 24,  3, 24, 24, 24,  4, 24, 24, 24, 24, 24, 24, 24, 24, 
  389. 24, 24,  2,  1, 24, 24,  6,  5, 24, 24, 24, 24, 24, 24, 24, 24, 
  390. -1, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  391. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  392. 24, 24, 24, 24, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  393. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  394. 24, 24, 24, 24, 19, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  395. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 20, 24, 24, 24, 24, 24, 
  396. 24, 24, 24,  3, 24, 24, 24,  4, 24, 24, 24, 24, 24, 24, 24, 24, 
  397. 24, 24,  2,  1, 24, 24,  6,  5, 24, 24, 24, 24, 24, 24, 24, 24, 
  398. -1, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  399. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  400. 24, 24, 24, 24, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  401. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  402. 24, 24, 24, 24, 24,  8, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  403. 24, 24, 24, 24, 24, 24, 24, 24, 24,  7, 24, 24, 24, 24, 24, 24, 
  404. 24, 24, 24,  3, 24, 24, 24,  4, 24, 24, 24, 24, 24, 24, 24, 24, 
  405. 24, 24,  2,  1, 24, 24,  6,  5, 24, 24, 24, 24, 24, 24, 24, 24, 
  406. -1, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  407. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  408. 24, 24, 24, 24, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  409. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  410. 24, 24, 24, 24, 24, 23, 17, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  411. 24, 24, 24, 16, 24, 24, 24, 24, 18, 15, 24, 24, 24, 24, 24, 24, 
  412. 24, 24, 24,  3, 24, 24, 24,  4, 24, 24, 24, 24, 24, 24, 24, 24, 
  413. 24, 24,  2,  1, 24, 24,  6,  5, 24, 24, 24, 24, 24, 24, 24, 24, 
  414. -1, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  415. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  416. 24, 24, 24, 24, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  417. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  418. 24, 24, 24, 24, 24, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  419. 24, 24, 24, 24, 24, 24, 24, 24, 24,  9, 24, 24, 24, 24, 24, 24, 
  420. 24, 24, 24,  3, 24, 24, 24,  4, 24, 24, 24, 24, 24, 24, 24, 24, 
  421. 24, 24,  2,  1, 24, 24,  6,  5, 24, 24, 24, 24, 24, 24, 24, 24, 
  422. -1, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  423. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  424. 24, 24, 24, 24, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  425. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  426. 24, 24, 24, 24, 24, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  427. 24, 24, 24, 24, 24, 24, 24, 24, 24, 10, 24, 24, 24, 24, 24, 24, 
  428. 24, 24, 24,  3, 24, 24, 24,  4, 24, 24, 24, 24, 24, 24, 24, 24, 
  429. 24, 24,  2,  1, 24, 24,  6,  5, 24, 24, 24, 24, 24, 24, 24, 24, 
  430. -1, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  431. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  432. 24, 24, 24, 24, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  433. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  434. 24, 24, 24, 24, 24, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  435. 24, 24, 24, 24, 24, 24, 24, 24, 24, 11, 24, 24, 24, 24, 24, 24, 
  436. 24, 24, 24,  3, 24, 24, 24,  4, 24, 24, 24, 24, 24, 24, 24, 24, 
  437. 24, 24,  2,  1, 24, 24,  6,  5, 24, 24, 24, 24, 24, 24, 24, 24, 
  438. -1, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  439. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  440. 24, 24, 24, 24, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  441. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  442. 24, 24, 24, 24, 24, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  443. 24, 24, 24, 24, 24, 24, 24, 24, 24, 12, 24, 24, 24, 24, 24, 24, 
  444. 24, 24, 24,  3, 24, 24, 24,  4, 24, 24, 24, 24, 24, 24, 24, 24, 
  445. 24, 24,  2,  1, 24, 24,  6,  5, 24, 24, 24, 24, 24, 24, 24, 24, 
  446.  0, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  447. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  448. 24, 24, 24, 24, 22, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  449. 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  450. 24, 24, 24, 24, 24, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 
  451. 24, 24, 24, 24, 24, 24, 24, 24, 24, 13, 24, 24, 24, 24, 24, 24, 
  452. 24, 24, 24,  3, 24, 24, 24,  4, 24, 24, 24, 24, 24, 24, 24, 24, 
  453. 24, 24,  2,  1, 24, 24,  6,  5, 24, 24, 24, 24, 24, 24, 24, 24, 
  454. };
  455.  
  456.  
  457. /* input
  458.  *
  459.  * provide packet type to state machine
  460.  */
  461. static int near input()
  462. {
  463.  
  464.     register int type;
  465.  
  466.     if (Kermit.start) {
  467.     type = Kermit.start;
  468.     Kermit.start = 0;
  469.     }
  470.     else {
  471.     type = krm_rpack();        /* read input */
  472.     if ((type != '$') && (type != 'E'))  {
  473.       /* packet is complete but is not an error packet */
  474.         if ((Kermit.seq != krm_rcvpkt.seq) || strchr("NQT", type)) {
  475.           /* something is wrong with packet */
  476.             if (Kermit.retries >= KermParams.RetryLimit) {
  477.           /* pretend we have an error packet */
  478.             krmCreatePseudoPacket('E', PS_DONE, IDS_KRM_TOOMANYRETRIES);
  479.             type = 'E';
  480.             }
  481.             else if ((type == 'N') && 
  482.               (krm_rcvpkt.seq == ((Kermit.seq + 1) & 63))) {
  483.           /* this is OK since NAK for next packet is ACK for previous */
  484.             type = 'Y';
  485.             Kermit.retries = 0;
  486.             }
  487.             else {
  488.           /* resend previous packet and try again */
  489.             Kermit.retries += 1;
  490.             Kermit.totalretries += 1;
  491.             krm_resend();
  492.             type = '$';
  493.             }
  494.         }
  495.         else    /* packet is OK; reset retry count */
  496.             Kermit.retries = 0;
  497.     }
  498.     }
  499.     return (type);
  500. }
  501.