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

  1. /*
  2.  * astutl.c Packet handling and misc. routines for ATARI ST kermit
  3.  */
  4.  
  5. #include <osbind.h>
  6. #include <stdio.h>
  7. #include "astinc.h"
  8. #include "astobj.h"
  9.  
  10. extern *msg_string();
  11.  
  12. /*
  13.  *   KERMIT utilities.
  14.  */
  15.  
  16.  
  17. /*
  18.  *  s p a c k
  19.  *
  20.  *  Send a Packet
  21.  */
  22.  
  23. spack(type,num,len,data)
  24. char type, *data;
  25. int num, len;
  26. {
  27.    int i;                          /* Character loop counter */
  28.    char chksum, buffer[100];       /* Checksum, packet buffer */
  29.    register char *bufp;            /* Buffer pointer */
  30.  
  31.    if (ibmmode)
  32.       wait_handshake();            /* if ibm mode wait for handshake */
  33.    if(type != 'Y' && type != 'N')
  34.       flushinput();                /* dump any leftovers */
  35.    len=len & 0x7f;                 /* Make sure len is not > 127  */
  36.    if (len > MAXPACKSIZ )          /* Make sure not larger than buffer */
  37.       len = MAXPACKSIZ-4;          /* IF so limit it  */
  38.  
  39.    msgdeb(MSGTLNPS,type,len,num);
  40.                                     /* Display outgoing packet */
  41.    if (data != NIL)
  42.       data[len] = '\0';             /* Null-terminate data to print it */
  43.    if (data != NIL)
  44.       msgdeb(MSGDATPS,data);
  45.  
  46.    bufp = buffer;                  /* Set up buffer pointer */
  47.  
  48.  
  49.    if (padding)                    /* Do padding */
  50.       for (i=1; i<=spad; i++)
  51.           Cauxout(spadc);
  52.    if (debug && (debug > 1)) msgdeb(MSGCHPAD,spad,spadc);
  53.  
  54.    *bufp++ = spcks;                /* Packet marker, usally SOH */
  55.    *bufp++ = tochar(len+3);        /* Send the character count */
  56.    chksum  = tochar(len+3);        /* Initialize the checksum */
  57.    *bufp++ = tochar(num);          /* Packet number */
  58.    chksum += tochar(num);          /* Update checksum */
  59.    *bufp++ = type;                 /* Packet type */
  60.    chksum += type;                 /* Update checksum */
  61.  
  62.    for (i=0; i<len; i++)           /* Loop for all data characters */
  63.    {
  64.       *bufp++ = data[i];           /* Get a character */
  65.       chksum += data[i];           /* Update checksum */
  66.    }
  67.    chksum = (((chksum&0300) >> 6)+chksum)&077; /* Compute final checksum */
  68.    *bufp++ = tochar(chksum);       /* Put it in the packet */
  69.    *bufp++ = seol;                 /* Extra-packet line terminator */
  70.    *bufp   = '\0';
  71.    auxsend(buffer);                /* Send the packet */
  72.    return(TRUE);
  73. }
  74.  
  75. /*
  76.  *  r p a c k
  77.  *
  78.  *  Read a Packet
  79.  */
  80.  
  81. char rpack(len,num,data)
  82. int *len, *num;                    /* Packet length, number */
  83. char *data;                        /* Packet data */
  84. {
  85.    int i,j, eolwc, done;           /* Data character number, loop exit */
  86.    int read_abort;                 /* 0 = timeout, 'A' = abort requested */
  87.    int abort;                      /* restart current packet */
  88.    char t,                         /* Current input character */
  89.    type,                           /* Packet type */
  90.    cchksum,                        /* Our (computed) checksum */
  91.    rchksum;                        /* Checksum received from other host */
  92.  
  93.    start_timer(&startpckt);
  94.    if (testat(&read_abort)) return(read_abort);
  95.    do {
  96.        if (readtimed(&t,&read_abort)) return(read_abort);
  97.       }
  98.    while ((t&127) != rpcks);       /* Wait for packet header */
  99.  
  100.    done = FALSE;                   /* Got SOH, init loop */
  101.    while (!done)                   /* Loop to get a packet */
  102.    {
  103.       if(readtimed(&t,&read_abort))
  104.         return(read_abort);        /* read character, or timeout */
  105.    /* if (!image)                     I guess, that's nonsense! */
  106.          t &= 0177;                /* Handle parity */
  107.       if (t == rpcks) continue;    /* Resynchronize if SOH */
  108.       cchksum = t;                 /* Start the checksum */
  109.       *len = unchar(t)-3;          /* Character count */
  110.  
  111.       if(readtimed(&t, &read_abort))
  112.         return(read_abort);        /* read character, or timeout */
  113.    /* if (!image)                     nonsense ? */
  114.          t &= 0177;                /* Handle parity */
  115.       if (t == rpcks) continue;    /* Resynchronize if SOH */
  116.       cchksum = cchksum + t;       /* Update checksum */
  117.       *num = unchar(t);            /* Packet number */
  118.  
  119.       if(readtimed(&t, &read_abort))
  120.         return(read_abort);        /* read character, or timeout */
  121.    /* if (!image)                     nonsense ? */
  122.          t &= 0177;                /* Handle parity */
  123.       if (t == rpcks) continue;    /* Resynchronize if SOH */
  124.       cchksum = cchksum + t;       /* Update checksum */
  125.       type = t;                    /* Packet type */
  126.       abort=FALSE;
  127.  
  128.       for (i=0; i<*len; i++)       /* The data itself, if any */
  129.       {            /* Loop for character count */
  130.          if(readtimed(&t, &read_abort))
  131.             return(read_abort);    /* read character, or timeout */
  132.          if (!image || ebq)
  133.             t &= 0177;             /* Handle parity */
  134.          if (t == rpcks) {         /* Resynch if SOH */
  135.             abort=TRUE;
  136.             break;
  137.          }
  138.          cchksum = cchksum + t;    /* Update checksum */
  139.          data[i] = t;              /* Put it in the data buffer */
  140.       }
  141.       if(abort)continue;
  142.       data[*len] = 0;              /* Mark the end of the data */
  143.  
  144.       if(readtimed(&t, &read_abort))
  145.         return(read_abort);        /* read character, or timeout */
  146.       t &= 0177;                   /* do not use parity bit of checksum */
  147.       rchksum = unchar(t);         /* Convert to numeric */
  148.       if (t == rpcks) continue;    /* Resynchronize if SOH */
  149.       done = TRUE;                 /* Got checksum, done */
  150.    }
  151.  
  152.    if (data != NIL)
  153.       data[*len] = '\0';           /* Null-terminate data to print it */
  154.    msgdeb(MSGTLNPR,type,*len,*num);
  155.    if (data != NIL)
  156.       msgdeb(MSGDATPR,data);
  157.  
  158.    /* Fold in bits 7,8 to compute */
  159.    cchksum = (((cchksum&0300) >> 6)+cchksum)&077; /* final checksum */
  160.  
  161.    if (cchksum != rchksum)
  162.    {
  163.       msgdeb(MSGCHKERR,rchksum,cchksum);
  164.       return(FALSE);
  165.    }
  166.  
  167.    /* wait for eol to avoid lost packages */
  168.    for (eolwc=0; eolwc<100; eolwc++)
  169.        if (Cauxis())
  170.           break;
  171.        else
  172.           evnt_timer(1,0);
  173.  
  174.    return(type);                   /* All OK, return packet type */
  175. }
  176.  
  177. /*
  178.  * compute 'universal time'
  179.  */
  180. long univ_time(t)
  181. int t;
  182. {
  183.  long int res;
  184.  res = 60 * ((t >> 11) & 0x1FL);
  185.  res = 60 * (res + ((t >> 5) & 0x3FL));
  186.  res = res + ((t & 0x1FL) << 1);
  187.  return (res);
  188. }
  189.  
  190. /*
  191.  * start timer
  192.  */
  193. start_timer(t0)
  194. long int *t0;
  195. {*t0 = univ_time(Tgettime());
  196. }
  197.  
  198. /*
  199.  * compute difference to start time
  200.  */
  201. int timer(t0)
  202. long int t0;
  203. {long int t1;
  204.  t1 = univ_time(Tgettime());
  205.  if (t1 < t0)
  206.     return ((int) (t1+(24*60*69)-t0));
  207.  else
  208.     return ((int) max((t1 - t0),1));
  209. }
  210.  
  211.  
  212.  
  213. /* readtimed: read a character or timeout
  214.  *            timeout is relative to start of waiting for packet
  215.  */
  216. readtimed(c,flag)
  217. char *c;     /* character received */
  218. int *flag;   /* flag showing reason for abort: 0=timeout,'A'=user aborted */
  219. {
  220.       while(!Cauxis())
  221.            {
  222.             *flag = sleepwait(50);
  223.             if (*flag == 'A') /* abort requested */
  224.                    {
  225.                     msgdeb(MSGUSRABO);
  226.                     return(TRUE);
  227.                    };
  228.             if (state == 'W')
  229.                start_timer(&startpckt);  /* no timeout in server wait */
  230.             if ((*flag == 'T') ||
  231.                 (stimint && dotimout && (timer(startpckt) >= stimint)))
  232.                {
  233.                 msgdeb(MSGTIMOUT);
  234.                 timcnt += 1;
  235.                 *flag = 0;
  236.                 return(TRUE);
  237.                };
  238.            };
  239.       *c = Cauxin();
  240.       if (debug && (deblevel > 1))
  241.          msgdeb(MSGCHRD,timer(startpckt),*c,(*c & 0x7F));
  242.       return(FALSE);
  243. }
  244.  
  245. /*
  246.  * test for abort or timeout request
  247.  */
  248. int testat(flag)
  249. int *flag;
  250. {
  251.  *flag = sleepwait(0);
  252.  if (*flag == 'A') /* abort requested */
  253.     {
  254.      msgdeb(MSGUSRABO);
  255.      return(TRUE);
  256.     };
  257.  if (*flag == 'T')
  258.     {
  259.      msgdeb(MSGTIMOUT);
  260.      timcnt += 1;
  261.      *flag = FALSE;
  262.      return(TRUE);
  263.     };
  264.  return(FALSE);
  265. }
  266.  
  267. /*
  268.  *  b u f i l l
  269.  *
  270.  *  Get a bufferful of data from the file that's being sent.
  271.  *  Only control-quoting is done; 8-bit & repeat count prefixes are
  272.  *  not handled. The last sentence is obsolete!
  273.  */
  274.  
  275. bufill(buffer)
  276. char buffer[];                      /* Buffer */
  277. {
  278.    int i,                           /* Loop index */
  279.    t;                               /* Char read from file */
  280.    char t7;                         /* 7-bit version of above */
  281.    char t9;                         /* dup of data char t  */
  282.    char b8;                         /* 8th bit */
  283.  
  284.    i = 0;                           /* Init data buffer pointer */
  285.    while(TRUE)
  286.      {
  287.       t = getc(fp);                /* Get the next character */
  288.       bytecnt++;
  289.       if (feof(fp)) break;
  290.       t9=t;                         /* Keep original pattern */
  291.       t7 = t & 0177;                /* Get low order 7 bits */
  292.       b8 = t & 0200;                /* Get MSB */
  293.  
  294.       if (ebq && b8 && image)
  295.          buffer[i++] = ebq;
  296.       if ((t7 < SP) || (t7==DEL) || (t7==squote)
  297.           || ((t7 == ebq) && ebq))
  298.                                     /* Does this char require */
  299.       {                             /* special handling? */
  300.          if (t=='\n' && !image)
  301.          {                          /* Do LF->CRLF mapping if !image */
  302.             buffer[i++] = squote;
  303.             buffer[i++] = ctl('\r');
  304.          }
  305.          buffer[i++] = squote;      /* Quote the character */
  306.          if ((t7 != squote) && ((t7 != ebq) || !ebq))
  307.          {
  308.             t = ctl(t);             /* and uncontrolify */
  309.             t7 = ctl(t7);
  310.          };
  311.       };
  312.       if (image && !ebq)
  313.          buffer[i++] = t;           /* Deposit the character itself */
  314.       else
  315.          buffer[i++] = t7;
  316.  
  317.  
  318.       if (i >= spsiz-8) return(i);  /* Check length */
  319.    }
  320.    if (i==0) return(EOF);           /* Wind up here only on EOF */
  321.    return(i);                       /* Handle partial buffer */
  322. }
  323.  
  324.  
  325. /*
  326.  *   b u f e m p
  327.  *
  328.  *  Put data from an incoming packet into a file.
  329.  */
  330.  
  331. bufemp(buffer,len)
  332. char  buffer[];                     /* Buffer */
  333. int   len;                          /* Length */
  334. {
  335.    int i;                           /* Counter */
  336.    char t;                          /* Character holder */
  337.    int b8;                          /* 8th bit flag */
  338.  
  339.    for (i=0; i<len; i++)            /* Loop thru the data field */
  340.    {
  341.       b8 = FALSE;
  342.       t = buffer[i];                /* Get character */
  343.       if (ebq && image && (ebq == (t & 0177)))
  344.          {b8 = TRUE; t = buffer[++i];
  345.          };
  346.       if (t == rquote)              /* Control quote? */
  347.       {
  348.          t = buffer[++i];           /* Get the quoted character */
  349.          if (((t & 0177) != rquote) &&
  350.              (((t & 0177) != ebq) || !ebq))
  351.                                     /* Low order bits match quote char? */
  352.             t = ctl(t);             /* No, uncontrollify it */
  353.       };
  354.       if (b8) t |= 0200;
  355.       putc(t,fp);
  356.       bytecnt++;
  357.    };
  358. }
  359.  
  360.  
  361. /*
  362.  *  s p a r
  363.  *
  364.  *  Fill the data array with my send-init parameters
  365.  *
  366.  */
  367.  
  368. spar(data)
  369. char data[];
  370. {
  371.    data[0] = tochar(rpsiz);       /* Biggest packet I can receive */
  372.    data[1] = tochar(rtimint);     /* When I want to be timed out */
  373.    data[2] = tochar(MYPAD);       /* How much padding I need */
  374.    data[3] = ctl(MYPCHAR);        /* Padding character I want */
  375.    data[4] = tochar(reol);        /* End-Of-Line character I want */
  376.    data[5] = squote;              /* Control-Quote character I send */
  377.    data[6] = (image ? MYEBQ : MYNOEBQ); /* 8 bit quoting */
  378. }
  379.  
  380.  
  381. /*  r p a r
  382.  *
  383.  *  Get the other host's send-init parameters
  384.  *
  385.  */
  386.  
  387. rpar(data)
  388. char data[];
  389. {  if((data[0]) != 0)
  390.       spsiz = unchar(data[0]);    /* Maximum send packet size */
  391.    if (data[1] != 0)
  392.       stimint = unchar(data[1]);  /* When I should time out */
  393.    if (data[2] != 0)
  394.       padding = spad = unchar(data[2]); /* Number of pads to send */
  395.    else
  396.       padding = spad = 0;
  397.    spadc = ctl(data[3]);          /* Padding character to send */
  398.    if ((data[4]) != 0)
  399.       seol = unchar(data[4]);     /* EOL character I must send */
  400.    else
  401.       seol = MYEOL;
  402.    if (data[5] != 0)
  403.       rquote = data[5];           /* Incoming data quote character */
  404.    else
  405.       rquote = MYQUOTE;
  406.    if (!image || (data[6] == 0) || (data[6] == 'N') || (data[6] == 'Y'))
  407.       ebq = FALSE;
  408.    else
  409.       ebq = data[6];
  410. }
  411.  
  412.  
  413. /*
  414.  *  f l u s h i n p u t
  415.  *
  416.  *  Dump all pending input to clear stacked up NACK's.
  417.  */
  418. flushinput()
  419. {char c;
  420.    /* TOS Clear AUX receive buffer   */
  421.    while (Cauxis())
  422.          {c = Cauxin();
  423.           if (debug && (deblevel > 1))
  424.               msgdeb(MSGCHFLU,c,(c & 0x7F));
  425.          };
  426. }
  427.  
  428. /*
  429.  * send one string to the aux port
  430.  */
  431. auxsend(str)
  432. char *str;
  433. {
  434.  while (*str != '\0')
  435.   {if (debug && (deblevel > 1)) msgdeb(MSGCHSND,*str,(*str & 0x7F));
  436.    Cauxout(*str++);
  437.   };
  438. }
  439.  
  440. /*
  441.  * wait for handshake character
  442.  */
  443. wait_handshake()
  444. /*
  445.  * wait for turnchar
  446.  * if received wait another 100 msecs and if no char received return.
  447.  * if no char received within 1000 msecs assume we missed turnchar
  448.  * otherwise return after a maximum of 4 secs
  449.  */
  450. {
  451.  int waitc;        /* wait counter */
  452.  char c;           /* last char read */
  453.  int nochrec;      /* no char received */
  454.  long int starthw; /* start time for wait */
  455.  waitc = 0;
  456.  start_timer(&starthw);
  457.  while (TRUE)
  458.      {if (timer(starthw) >= 4) break;
  459.       if ((waitc >= 10) && !Cauxis()) break;
  460.       if (Cauxis())
  461.          {waitc = 0;
  462.           while (Cauxis())
  463.                 {c = Cauxin() & 0x7F;
  464.                  if (debug && (deblevel > 1)) msgdeb(MSGCHWHC,c,c);
  465.                 };
  466.          };
  467.       evnt_timer(100,0);
  468.       if ((c == rturnchar) && !Cauxis())
  469.          {msgdeb(MSGHNDOK);
  470.           return(FALSE);
  471.          };
  472.       waitc++;
  473.      };
  474.  msgdeb(MEGHNDFA);
  475.  return(FALSE);
  476. }
  477.  
  478. /*
  479.  *  Kermit printing routines:
  480.  *
  481.  */
  482.  
  483.  
  484. /*
  485.  *  Print message on DEBUG file
  486.  *  First arg is object index of the KRMESSS object
  487.  */
  488.  
  489. msgdeb(fmtix, a1, a2, a3, a4, a5)
  490. int fmtix;
  491. long a1,a2,a3,a4,a5;
  492. {
  493.  if (debug)
  494.      {
  495.       fprintf(deb,msg_string(fmtix),a1,a2,a3,a4,a5);
  496.       putc('\n',deb);
  497.      };
  498. }
  499.  
  500.  
  501.  
  502. /*
  503.  * Print message on LOG file
  504.  * if first arg >= 0 then display an alert box too
  505.  */
  506. msglog(alertix,fmtix,a1,a2,a3,a4,a5)
  507. int fmtix, alertix;
  508. long a1, a2, a3, a4, a5;
  509. {
  510.  if (translog)
  511.     {
  512.      fprintf(log,msg_string(fmtix),a1,a2,a3,a4,a5);
  513.      putc('\n',log);
  514.     };
  515.  if (alertix >= 0)
  516.     displ_alert(1,alertix);
  517. }
  518.  
  519. /*
  520.  * Print message on DEBUG and LOG file
  521.  * and perhaps display an alert box
  522.  */
  523. msgall(alertix,fmtix,a1,a2,a3,a4,a5)
  524. int fmtix, alertix;
  525. {
  526.  msgdeb(fmtix,a1,a2,a3,a4,a5);
  527.  msglog(alertix,fmtix,a1,a2,a3,a4,a5);
  528. }
  529.  
  530.  
  531. /*
  532.  *  p r e r r p k t
  533.  *
  534.  *  Print contents of error packet received from remote host.
  535.  */
  536. prerrpkt(msg)
  537. char *msg;
  538. {
  539.  msgall(-1,MSGERRPK,msg);
  540.  displ_pckerr(msg);
  541. }
  542.