home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / c / cuj9301.zip / 1101066A < prev    next >
Text File  |  1992-11-03  |  3KB  |  109 lines

  1. boolean
  2. fgsenddata (zdata, cdata)
  3.      char *zdata;
  4.      int cdata;
  5. {
  6.   char *z;
  7.   int itt, iseg, csize;
  8.   unsigned short icheck;
  9.  
  10.   itt = DATA;
  11.   csize = iGremote_packsize;
  12.   iseg = iGremote_segsize + 1;
  13.  
  14.   if (cdata < iGremote_packsize)
  15.     {
  16.       /* If the remote packet size is larger than 64, the default, we
  17.      can assume they can handle a smaller packet as well, which
  18.      will be more efficient to send.  */
  19.       if (iGremote_packsize > 64)
  20.     {
  21.       /* The packet size is 1 << (iseg + 4).  */
  22.       iseg = 1;
  23.       csize = 32;
  24.       while (csize < cdata)
  25.         {
  26.           csize <<= 1;
  27.           ++iseg;
  28.         }
  29.     }
  30.  
  31.       if (csize != cdata)
  32.     {
  33.       int cshort;
  34.  
  35.       /* We have to move the data within the packet,
  36.          unfortunately.  It only happens once per file transfer.
  37.          It would also be nice if we computed the checksum as we
  38.          move.  We zero out the unused bytes.  */
  39.       itt = SHORTDATA;
  40.       cshort = csize - cdata;
  41.       if (cshort <= 127)
  42.         {
  43.           memmove (zdata + 1, zdata, cdata);
  44.           zdata[0] = (char) cshort;
  45.           memset (zdata + cdata + 1, 0, cshort - 1);
  46.         }
  47.       else
  48.         {
  49.           memmove (zdata + 2, zdata, cdata);
  50.           zdata[0] = (char) (0x80 | (cshort & 0x7f));
  51.           zdata[1] = (char) (cshort >> 7);
  52.           memset (zdata + cdata + 2, 0, cshort - 2);
  53.         }
  54.     }
  55.     }
  56.  
  57.   z = zdata - CFRAMELEN;
  58.  
  59.   z[IFRAME_DLE] = DLE;
  60.   z[IFRAME_K] = (char) iseg;
  61.  
  62.   icheck = (unsigned short) igchecksum (zdata, csize);
  63.  
  64.   /* Wait until there is room in the receiver's window for us to send
  65.      the packet.  We do this now so that we send the correct value for
  66.      the last packet received.  Note that if iGsendseq ==
  67.      iGremote_ack, this means that the sequence numbers are actually 8
  68.      apart, since the packet could not have been acknowledged before
  69.      it was sent; this can happen when the window size is 7.  */
  70.   while (iGsendseq == iGremote_ack
  71.      || CSEQDIFF (iGsendseq, iGremote_ack) > iGremote_winsize)
  72.     {
  73.       if (! fgwait_for_packet (TRUE, cGtimeout, cGretries))
  74.     return FALSE;
  75.     }
  76.  
  77.   /* Ack all packets up to the next one, since the UUCP protocol
  78.      requires that all packets be acked in order.  */
  79.   while (CSEQDIFF (iGrecseq, iGlocal_ack) > 1)
  80.     {
  81.       iGlocal_ack = INEXTSEQ (iGlocal_ack);
  82.       if (! fgsend_control (RR, iGlocal_ack))
  83.     return FALSE;
  84.     }
  85.   iGlocal_ack = iGrecseq;
  86.  
  87.   z[IFRAME_CONTROL] = (char) ((itt << 6) | (iGsendseq << 3) | iGrecseq);
  88.  
  89.   iGsendseq = INEXTSEQ (iGsendseq);
  90.  
  91.   icheck = ((unsigned short)
  92.         ((0xaaaa - (icheck ^ (z[IFRAME_CONTROL] & 0xff))) & 0xffff));
  93.   z[IFRAME_CHECKLOW] = (char) (icheck & 0xff);
  94.   z[IFRAME_CHECKHIGH] = (char) (icheck >> 8);
  95.  
  96.   z[IFRAME_XOR] = (char) (z[IFRAME_K] ^ z[IFRAME_CHECKLOW]
  97.               ^ z[IFRAME_CHECKHIGH] ^ z[IFRAME_CONTROL]);
  98.  
  99.   /* If we're waiting for acks of retransmitted packets, then don't
  100.      send this packet yet.  The other side may not be ready for it
  101.      yet.  Instead, code in fggot_ack will send the outstanding
  102.      packets when an ack is received.  */
  103.   if (iGretransmit_seq != -1)
  104.     return TRUE;
  105.  
  106.   return fsend_data (z, CFRAMELEN + csize, TRUE);
  107. }
  108.  
  109.