home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / researchmachines / rmllin.c < prev    next >
Text File  |  1985-07-10  |  11KB  |  452 lines

  1.  
  2. /***********************************************************************/
  3.  
  4. /*  File  KLINE.C  -  Comms-line handling procedures for RML Kermit;
  5.         Chris Kennington    RML.    9th July 1985.    */
  6.  
  7. #define     DEFS1    1
  8. #define     DEFS2    1
  9.  
  10. #include  "stdio.h"
  11. #include  "b:kext.h"
  12.  
  13.  
  14. /* local globals for nextin/nextout        */
  15. static    int    fuzzy = 20000;    /* arbitry value */    
  16. static    int    ret;
  17. static    char    dummy, typout;
  18. static  char    comerr[] = "Comms err %x";
  19. static    char    enter[]  = " Enter %s for mainframe:\r> ";
  20.  
  21.  
  22. connect()        /* keyboard/screen to comms line relay    */
  23. /* Reads keyboard and transmits to line; reads line and outputs to
  24.     screen; checks comms line for error conditions.        */
  25. {
  26.     char  c, cn, conn;
  27.     static  char  pager = 0, *data[5];
  28.     int   in;
  29.  
  30.     printmsg("Connecting you to remote mainframe ...  ");
  31.     keyconn();                /* make arrows valid    */
  32.     outc(NL);
  33.     kmode = CONN;
  34.     while (kmode == CONN) {        /* until stopped    */
  35.     if (keyget(&c) != 0) {
  36.         if (echo != 0)
  37.         outc(c);
  38.         cn = 100;
  39.         while (cn-- > 0)
  40.         if (s4put(1,&c) > 0)
  41.             break;
  42.         if (cn == 0)
  43.         bell();
  44.     }
  45.     if ( (in = s4get7(1,&data)) == 1 ) {
  46. #ifndef MPUZ80
  47.       if (*data != LF)
  48. #endif
  49.         outfc(*data);
  50.     }
  51.     else if (in != 0) {
  52.         outc(NL);
  53.         printmsg("Comms error code %x; ", in);
  54.         while (s4test() == in)
  55.         ;
  56.     }        
  57.     }            /* end switch            */
  58.   /* broken out    by changing kmode            */
  59.     return;
  60. }        /* End of connect()            */
  61.  
  62.  
  63.  
  64.  
  65. flushinput()
  66. /*  Dump all pending input to clear stacked up NAK's. */
  67. {
  68.     char  rubbish[11];
  69.  
  70.     while (s4get(10,rubbish) > 0)
  71.     ;
  72. }            /* end of flushinput        */
  73.  
  74.  
  75.  
  76. inctry()        /* increment tries & pkt-#    */
  77. /* used by both recieve & send routines            */
  78. {
  79.     oldtry = numtry;
  80.     numtry = 0;
  81.     n = (n+1)%64;
  82.     return;
  83. }            /* end of inctry()        */
  84.  
  85.  
  86.  
  87. /* Line-I/O Routines for sending/receiving files        */
  88.  
  89. static nextab()        /* set abort-flag if CTLC        */
  90. {
  91.     if (dummy == CTLC) {    /* treat ctlc as abort    */
  92.     printmsg("Abort transfer");
  93.     if (confirm() == TRUE)
  94.         abtflag = 1;
  95.     dummy = 0;
  96.     }
  97.     return;
  98. }            /* end of nextab()            */
  99.  
  100. nextin(ic)            /* next char from line        */
  101. /* strips parity bit if !image; handles fuzzy timeout;
  102.    returns 0, but 1 if either abtflag or nakflag has been set    */
  103. char  *ic;
  104. {
  105.     int        r;
  106.  
  107.     abtflag = nakflag = 0;
  108. One:
  109.     while ( (ret = (image) ? s4get(1,ic) : s4get7(1,ic)) == 0 ) {
  110.     keyget(&dummy);
  111.     nextab();
  112.     if ( (abtflag+nakflag) != 0 )
  113.         return(1);
  114.     if (--fuzzy == 0) {    /* timer expired    */
  115.         nakflag = 1;
  116.         ++timouts;
  117.         if (list == 1)
  118.         outc('T');
  119.         if (list > 2)
  120.         txtout("\rDbg: Timeout.");
  121.         return(1);
  122.     }   }
  123.     while (ret < 0) {        /* error        */
  124.     printmsg(comerr,ret);
  125.     while ( (r = (image) ? s4get(1,ic) : s4get7(1,ic)) == ret) {
  126.         keyget(&dummy);
  127.         if ( (abtflag+nakflag) != 0 )
  128.         return(1);
  129.     }
  130.     if (r == 0)
  131.         goto One;
  132.     ret = r;
  133.     }
  134.     if (list > 4)
  135.     outc(*ic);
  136.     if (*ic == SOH)    
  137.     fuzzy = fuzz[env]; /* fuzzy timer re-set on SOH only */
  138.     return(abtflag+nakflag);
  139. }            /* end of nextin()        */
  140.  
  141.  
  142.  
  143. nextout(c)        /* next char to line        */
  144. /* returns 0, but 1 if either abtflag or nakflag has been set    */
  145. char  c;
  146. {
  147.     int  r;
  148.  
  149.     abtflag = nakflag = 0;
  150. One:
  151.     while ( (ret = s4put(1,&c)) == 0 ) {
  152.     keyget(&dummy);
  153.     nextab();
  154.     if ( (abtflag+nakflag) != 0 )
  155.         return(1);
  156.     }
  157.     while (ret < 0) {        /* error        */
  158.     printmsg(comerr,ret);
  159.     while ( (r = s4put(1,&c)) == ret) {
  160.         keyget(&dummy);
  161.         if ( (abtflag+nakflag) != 0 )
  162.         return(1);
  163.         }
  164.     if (r == 0)
  165.         goto One;
  166.     ret = r;
  167.     }
  168.     if (list > 4)
  169.     outc(c);
  170.     keyget(&dummy);
  171.     return(abtflag+nakflag);
  172. }            /* end of nextout()        */
  173.  
  174.  
  175.  
  176. char  rpack(len,num,data)    /*  Read a Packet        */
  177. /*  If !image, nextin() has stripped the parity bit.        */
  178. int *len, *num;                /* Packet length, number */
  179. char *data;                /* Packet data */
  180. {
  181.     int i, done;            /* Data character number, loop exit */
  182.     char t,                /* Current input character */
  183.     cchksum,            /* Our (computed) checksum */
  184.     rchksum;            /* Checksum received from other host */
  185.     static int oldnum = 63;
  186.  
  187. Top:
  188.     fuzzy = fuzz[env];            /* set timer        */
  189.     t = type = 0;            /* could be garbage    */
  190.     *len = 0;                /* in case timeout    */
  191.     while (t != SOH) if (nextin(&t) != 0) {
  192.         type = 'T';
  193.         goto Flag;
  194.     }
  195.  
  196.     done = FALSE;            /* Got SOH, init loop */
  197.     while (!done) {            /* Loop to get a packet */
  198.     if (nextin(&t) != 0)        /* Get length character */
  199.         break;
  200.     cchksum = t;            /* Start the checksum */
  201.     if (t == SOH)
  202.         continue;            /* Resynchronize if SOH */
  203.     t &= 0x7f;            /* 7-bit protocol char    */
  204.     if ( (*len = unchar(t)-3) < 0 )    /* Character count */
  205.         return(FALSE);        /* protect against bad length    */
  206.     if (nextin(&t) != 0)        /* Get packet-number character */
  207.         break;
  208.     cchksum = cchksum + t;        /* Update checksum */
  209.     t &= 0x7f;            /* 7-bit protocol char    */
  210.     if (t == SOH)
  211.         continue;            /* Resynchronize if SOH */
  212.     *num = unchar(t);        /* Packet number */
  213.     if (*num == oldnum)
  214.         ++dupes;            /*  its a duplicate    */
  215.     else
  216.         oldnum = *num;
  217.     vtout(LOCSEQ,t|0x80);
  218.  
  219.     if (nextin(&t) != 0)        /* Get packet-type character */
  220.         break;
  221.     cchksum = cchksum + t;        /* Update checksum */
  222.     t &= 0x7f;            /* 7-bit protocol char    */
  223.     if (t == SOH)
  224.         continue;            /* Resynchronize if SOH */
  225.     if ( (type = t) == 'N' ) {
  226.         ++naxin;            /*  its a NAK    */
  227.         if (list == 1)
  228.         outc('N');
  229.     }
  230.     if (type == typout)
  231.         goto Top;            /* its an echo        */
  232.     vtout(LOCIN,type);
  233.  
  234.     for (i=0; i<*len; i++) {    /* The data itself, if any */
  235.         if (nextin(&t) != 0)    /* Get data character */
  236.         break;
  237.         cchksum = cchksum + t;    /* Update checksum */
  238.         data[i] = t;        /* Put it in the data buffer */
  239.         t &= 0x7f;            /* 7-bit char        */
  240.         if (t == SOH) break;    /* stop if SOH */
  241.     }
  242.     if (t == SOH)
  243.         continue;            /* Resynchronize if SOH */
  244.     if ( (nakflag+abtflag) != 0 )
  245.         break;
  246.     data[*len] = 0;            /* Mark the end of the data */
  247.  
  248.     if (nextin(&t) != 0)        /* Get checksum character */
  249.         break;
  250.     rchksum = unchar(t);        /* Convert to numeric */
  251.     done = TRUE;            /* Got checksum, done */
  252.     }
  253.     flushinput();            /* discard anything stacked */
  254.     if ( (list > 3) && ( (nakflag+abtflag) == 0 ) ) {    /* Display    */
  255.     outc(CR);
  256.     printf("  Packet in: type %c, num %d, len%d;",type,*num,*len);
  257.     outc(CR);
  258.     if (*len != 0) {
  259.         data[*len] = 0;
  260.         printf("  data: \"%s\";",data);
  261.         outc(CR);
  262.     }    }
  263.  
  264. Flag:                /* check for user abort or nak    */
  265.     vtout(LOCIN,type|0x80);        /* inverse of type    */
  266.     if (nakflag != 0)
  267.     return(FALSE);            /* cause NAK to be sent    */
  268.     if (abtflag != 0) {
  269.     abtflag = 0;
  270.     return('A');            /* cause ABORT        */
  271.     }
  272.                     /* Fold in bits 7,8 to compute */
  273.     cchksum = (((cchksum&0300) >> 6)+cchksum)&077; /* final checksum */
  274.  
  275.     if (cchksum == rchksum) {
  276.     if (type == 'D')
  277.         blockmv(oldpkt,data,*len);    /* copy for reference    */
  278.      return(type);            /* OK return        */
  279.     }
  280.     ++badcrcs;                /* count bad checksum    */
  281.     if (list == 1)
  282.     outc('C');
  283.     else if (list > 2)
  284.     txtout(" Bad checksum ");
  285.     return(FALSE);
  286. }            /* end of rpack()            */
  287.  
  288.  
  289.  
  290. servsend(type)        /* send command to server-Kermit etc.    */
  291. char    type;
  292. {
  293.     int        *len, *num;
  294.     char    pkt;
  295.  
  296.     switch(type) {
  297.  
  298.       case RMSV:        /* Server Commands        */
  299.     pkt = 'K';            /* packet-type        */
  300.     goto Rmcont;
  301.  
  302.       case RMH:            /* OS Commands            */
  303.     pkt = 'C';            /* packet-type        */
  304. Rmcont:
  305.     txtout(" Calling mainframe ... ");
  306.     if (parex() == 0) {        /* exchange parameters    */
  307.         printmsg("Mainframe Kermit seems dead ");
  308.         kmode = KERM;
  309.         break;
  310.     }
  311.     else forever {
  312.         printmsg(enter,"message");
  313.         if (keyline(packet) == 0) {
  314.         kmode = CMND;
  315.         break;
  316.         }
  317.         printmsg("Telling mainframe ... ");
  318.         recsw(type,pkt);
  319.     }
  320.     break;
  321.  
  322.       case GET:            /* fetch files            */
  323.     printf(inform);
  324.     printmsg(enter,"filenames");
  325.     if (keyline(packet) == 0)
  326.         kmode = KERM;
  327.     else {
  328.         vtline(LOCMODE,rcvng);
  329.         state = kmode = GET;
  330.     }
  331.     break;
  332.  
  333.       case SEND:        /* send files            */
  334.     vtline(LOCMODE,sendf);
  335.     kmode = SEND;
  336.     break;
  337.  
  338.       case BYE:            /* logout from mainframe    */
  339.     spack('G',n,1,"L");        /* generic logout    */
  340.     kmode = KERM;
  341.     outc(SP);
  342.     txtout(trying);
  343.     rpack(&len,&num,recpkt);
  344.     if (len != 0) {
  345.         recpkt[*len] = 0;
  346.         printmsg("%s %s",mainsays,recpkt);
  347.     }
  348.     break;
  349.  
  350.       case LOGO:        /* cancel mainframe Kermit    */
  351.     spack('G',n,1,"F");        /* try "Finish"        */
  352.     txtout(dots);
  353.     if (rpack(&len,&num,recpkt) != 'Y') /* synchronize    */
  354.         spack('E',0,strlen(errmsg),errmsg);
  355.     vtline(LOCMODE,connto);
  356.     kmode = CONN;
  357.     break;
  358.  
  359.       case QUIT:        /* cancel (local) Kermit    */
  360.     kermkill(1);
  361.  
  362.       case MAIN:        /* back to top level        */
  363.     kmode = KERM;
  364.     break;
  365.  
  366.     }            /* end switch                */
  367.     return;
  368. }            /* end of servsend()            */
  369.  
  370.  
  371.  
  372. setbaud()        /* set line-speed from spdcode    */
  373. {
  374.     vtline(LOCSPEED+3,"  ");
  375.     vtline(LOCSPEED,spval[spdcode]);
  376.     s4speed(spdcode);
  377.     return;
  378. }            /* end of setbaud()        */
  379.  
  380.  
  381.  
  382. setpar()        /* set parity from parity    */
  383. {
  384.     commode &= 0xfcff;        /* remove parity bits    */
  385.     commode |= (int)parity * 256; /* substitute new    */
  386.     s4set(commode,comctrl);
  387.     return;
  388. }            /* end of setpar()        */
  389.  
  390.  
  391.  
  392. spack(type,num,len,data)        /*  Send a Packet */
  393. char type, *data;
  394. int num, len;
  395. {
  396.     int i;                /* Character loop counter */
  397.     char     c, chksum;
  398.     register char *bufp;        /* Buffer pointer */
  399.     static  int  cumnum = 0;
  400.  
  401.     if (list > 3) {            /* Display outgoing packet */
  402.     outc(CR);
  403.     printf("  Packet out: type %c, num %d, len %d:",type,num,len);
  404.     outc(CR);
  405.     if (len != 0) {
  406.         data[len] = 0;
  407.         printf("  data: \"%s\";",data);
  408.         outc(CR);
  409.     }    }
  410.  
  411.     vtout(LOCOUT,type);
  412.     vtout(LOCSEQ,tochar(n));
  413.     sprintf(work,"%d =",cumnum++);
  414.     vtline(LOCPKTS,work);
  415.  
  416.     for (i=1; i<=pad; i++)
  417.     if (nextout(&padchar) != 0)    /* padding    */
  418.         return;
  419.     bufp = work;            /* buffer pointer */
  420.     *bufp++ = SOH;
  421.     *bufp++ = tochar(len+3);
  422.     chksum  = tochar(len+3);
  423.     *bufp++ = tochar(num);
  424.     chksum += tochar(num);
  425.     typout = *bufp++ = type;
  426.     chksum += type;
  427.  
  428.     for (i=0; i<len; i++) {        /* for all data characters */
  429.     *bufp++ = c = data[i];
  430.     chksum += c;
  431.     }
  432.     chksum = (((chksum&0300) >> 6)+chksum)&077; /* Compute final checksum */
  433.     *bufp++ = tochar(chksum);
  434.     *bufp++ = eol;            /* Extra-packet line terminator */
  435.     *bufp = CR;                /*  & CR for safety        */
  436.     len = bufp-work+1;
  437.     bufp = work;
  438.     while (len-- > 0)
  439.     if (nextout(*bufp++) != 0)
  440.         break;
  441.     vtout(LOCOUT,type|0x80);        /* inverse of type        */
  442.     if (netslow)            /* discard any buffered dupes    */
  443.     flushinput();
  444.     return;
  445. }            /* end of spack()                */
  446.  
  447.  
  448.  
  449. /**********************  End of KLINE.C  **************************/
  450.  
  451.  
  452.