home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / EXTRAS / UUCODE / UUPC / TEST / UPC12ES2.ZIP / UUCICO / dcpfpkt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-07  |  18.7 KB  |  551 lines

  1. /*--------------------------------------------------------------------*/
  2. /*       d c p f p k t . c                                            */
  3. /*                                                                    */
  4. /*       UUCP 'f' protocol support                                    */
  5. /*--------------------------------------------------------------------*/
  6.  
  7. /*--------------------------------------------------------------------*/
  8. /*       Changes Copyright (c) 1989-1993 by Kendra Electronic         */
  9. /*       Wonderworks.                                                 */
  10. /*                                                                    */
  11. /*       All rights reserved except those explicitly granted by       */
  12. /*       the UUPC/extended license agreement.                         */
  13. /*--------------------------------------------------------------------*/
  14.  
  15. /*--------------------------------------------------------------------*/
  16. /*                          RCS Information                           */
  17. /*--------------------------------------------------------------------*/
  18.  
  19. /*
  20.  *    $Id: dcpfpkt.c 1.14 1993/11/06 17:57:09 rhg Exp $
  21.  *
  22.  *    Revision history:
  23.  *    $Log: dcpfpkt.c $
  24.  * Revision 1.14  1993/11/06  17:57:09  rhg
  25.  * Drive Drew nuts by submitting cosmetic changes mixed in with bug fixes
  26.  *
  27.  * Revision 1.13  1993/10/09  22:21:55  rhg
  28.  * ANSIfy source
  29.  *
  30.  * Revision 1.12  1993/10/02  19:07:49  ahd
  31.  * Suppress compiler warning
  32.  *
  33.  * Revision 1.11  1993/09/20  04:41:54  ahd
  34.  * OS/2 2.x support
  35.  *
  36.  * Revision 1.10  1993/07/31  16:27:49  ahd
  37.  * Changes in support of Robert Denny's Windows support
  38.  *
  39.  * Revision 1.9  1993/07/22  23:22:27  ahd
  40.  * First pass at changes for Robert Denny's Windows 3.1 support
  41.  *
  42.  * Revision 1.8  1993/05/30  00:01:47  ahd
  43.  * Multiple communications driver support
  44.  *
  45.  * Revision 1.7  1993/04/05  12:26:01  ahd
  46.  * Correct prototypes to match gpkt
  47.  *
  48.  * Revision 1.6  1993/04/05  04:35:40  ahd
  49.  * Allow unique send/receive packet sizes
  50.  *
  51.  * Revision 1.3  1992/11/19  02:36:29  ahd
  52.  * Revision 1.2  1992/11/15  20:10:47  ahd
  53.  * Clean up modem file support for different protocols
  54.  */
  55.  
  56. /*--------------------------------------------------------------------*/
  57. /*    Flow control ("f") protocol.                                    */
  58. /*                                                                    */
  59. /*    This protocol relies on flow control of the data stream.  It    */
  60. /*    is meant for working over links that can (almost) be            */
  61. /*    guaranteed to be errorfree, specifically X.25/PAD links.  A     */
  62. /*    sumcheck is carried out over a whole file only.  If a           */
  63. /*    transport fails the receiver can request retransmission(s).     */
  64. /*    This protocol uses a 7-bit datapath only, so it can be used     */
  65. /*    on links that are not 8-bit transparent.                        */
  66. /*                                                                    */
  67. /*    When using this protocol with an X.25 PAD:  Although this       */
  68. /*    protocol uses no control chars except CR, control chars NULL    */
  69. /*    and ^P are used before this protocol is started; since ^P is    */
  70. /*    the default char for accessing PAD X.28 command mode, be        */
  71. /*    sure to disable that access (PAD par 1).  Also make sure        */
  72. /*    both flow control pars (5 and 12) are set.  The CR used in      */
  73. /*    this proto is meant to trigger packet transmission, hence       */
  74. /*    par 3 should be set to 2; a good value for the Idle Timer       */
  75. /*    (par 4) is 10.  All other pars should be set to 0.              */
  76. /*                                                                    */
  77. /*    Normally a calling site will take care of setting the local     */
  78. /*    PAD pars via an X.28 command and those of the remote PAD via    */
  79. /*    an X.29 command, unless the remote site has a special           */
  80. /*    channel assigned for this protocol with the proper par          */
  81. /*    settings.                                                       */
  82. /*                                                                    */
  83. /*    Author:  Piet Beertema, CWI, Amsterdam, Sep 1984                */
  84. /*                                                                    */
  85. /*    Adapted to uupc 3.0 and THINK C 4.0 by Dave Platt, Jul 1991     */
  86. /*                                                                    */
  87. /*    Adapted to UUPC/extended by Drew Derbyshire, 1992               */
  88. /*--------------------------------------------------------------------*/
  89.  
  90. /*--------------------------------------------------------------------*/
  91. /*                        System include files                        */
  92. /*--------------------------------------------------------------------*/
  93.  
  94. #include <stdio.h>
  95. #include <time.h>
  96. #include <string.h>
  97.  
  98. /*--------------------------------------------------------------------*/
  99. /*                    UUPC/extended include files                     */
  100. /*--------------------------------------------------------------------*/
  101.  
  102. #include "lib.h"
  103. #include "dcp.h"
  104. #include "dcpfpkt.h"
  105. #include "dcpsys.h"
  106. #include "hostable.h"
  107. #include "security.h"
  108. #include "ssleep.h"
  109. #include "modem.h"
  110. #include "commlib.h"
  111.  
  112. /*--------------------------------------------------------------------*/
  113. /*                              Defines                               */
  114. /*--------------------------------------------------------------------*/
  115.  
  116. #ifndef MAXMSGLEN
  117. #define MAXMSGLEN BUFSIZ
  118. #endif /* MAXMSGLEN */
  119.  
  120. currentfile();
  121.  
  122. /*--------------------------------------------------------------------*/
  123. /*                    Internal function prototypes                    */
  124. /*--------------------------------------------------------------------*/
  125.  
  126. static short fsendresp(short state);
  127.  
  128. /*--------------------------------------------------------------------*/
  129. /*                          Global variables                          */
  130. /*--------------------------------------------------------------------*/
  131.  
  132. static short chksum;
  133.  
  134. /*--------------------------------------------------------------------*/
  135. /*    f o p e n p k                                                   */
  136. /*                                                                    */
  137. /*    Open "f" protocol to other system                               */
  138. /*--------------------------------------------------------------------*/
  139.  
  140. #ifdef __TURBOC__
  141. #pragma argsused
  142. #elif _MSC_VER >= 700
  143. #pragma warning(disable:4100)   /* suppress unref'ed formal param. warnings */
  144. #endif
  145.  
  146. short fopenpk(const boolean master)
  147. {
  148.    flowcontrol(TRUE);
  149.  
  150.    if ( M_fPacketSize > MAXPACK)
  151.       M_fPacketSize = MAXPACK;
  152.  
  153.    r_pktsize = s_pktsize = M_fPacketSize;
  154.    ssleep(2); /* Give peer time to perform corresponding port setup */
  155.    return DCP_OK;
  156. } /* fopenpk */
  157.  
  158. #if _MSC_VER >= 700
  159. #pragma warning(default:4100)   /* restore unref'ed formal param. warnings */
  160. #endif
  161.  
  162. /*--------------------------------------------------------------------*/
  163. /*    f c l o s e p k                                                 */
  164. /*                                                                    */
  165. /*    Shutdown "f" procotol with other system                         */
  166. /*--------------------------------------------------------------------*/
  167.  
  168. short fclosepk()
  169. {
  170.    flowcontrol(FALSE);
  171.    return DCP_OK;
  172. } /* fclosepk */
  173.  
  174. /*--------------------------------------------------------------------*/
  175. /*    f w r m s g                                                     */
  176. /*                                                                    */
  177. /*    Send a control message to remote system with "f" procotol       */
  178. /*--------------------------------------------------------------------*/
  179.  
  180. short fwrmsg(char *str)
  181. {
  182.    char bufr[MAXMSGLEN];
  183.    char *s = bufr;
  184.  
  185.    while (*str)
  186.       *s++ = *str++;
  187.    if (*(s-1) == '\n')
  188.       s--;
  189.    *s++ = '\r';
  190.    if (swrite(bufr, (unsigned int) (s - bufr)) == (int)(s - bufr))
  191.       return DCP_OK;
  192.    else
  193.       return DCP_FAILED;
  194. } /* fwrmsg */
  195.  
  196. /*--------------------------------------------------------------------*/
  197. /*    f r d m s g                                                     */
  198. /*                                                                    */
  199. /*    Read a control message from remote host with "f" protocol       */
  200. /*--------------------------------------------------------------------*/
  201.  
  202. short frdmsg(char *str)
  203. {
  204.    char *smax;
  205.    char *s = str;
  206.  
  207.    smax = s + MAXPACK - 1;
  208.    for (;;) {
  209.       if (sread(s, 1, M_fPacketTimeout) <= 0)
  210.       {
  211.          printmsg(0,"frdmsg: timeout reading message");
  212.          *s++ = '\0';
  213.          goto msgerr;
  214.       }
  215.       if (*s == '\r')
  216.          break;
  217.       if (*s < ' ')
  218.          continue;
  219.       if (s++ >= smax)
  220.       {
  221.          printmsg(0,"frdmsg: buffer overflow");
  222.          *--s = '\0';
  223.          goto msgerr;
  224.       } /* if (s++ >= smax) */
  225.    }
  226.    *s = '\0';
  227.    return DCP_OK;
  228.  
  229. msgerr:
  230.    printmsg(0,"frdmsg: Message received \"%s\"", str);
  231.    return DCP_FAILED;
  232. } /* frdmsg */
  233.  
  234. /*--------------------------------------------------------------------*/
  235. /*    f g e t p k t                                                   */
  236. /*                                                                    */
  237. /*    Receive an "f" protocol packet of data from the other system    */
  238. /*--------------------------------------------------------------------*/
  239.  
  240. short fgetpkt(char *packet, short *bytes)
  241. {
  242.    char *op, c, *ip;
  243.    short sum, len, left;
  244.    char buf[5], tbuf[1];
  245.    short i;
  246.    static char special = 0;
  247.    static boolean eof = FALSE;
  248.  
  249. /*--------------------------------------------------------------------*/
  250. /*                    Handle EOF on previous call                     */
  251. /*--------------------------------------------------------------------*/
  252.  
  253.    if ( eof )
  254.    {
  255.       eof = FALSE;
  256.       printmsg(2,"fgetpkt: EOF from other host");
  257.       *bytes = 0;
  258.       if (fsendresp(DCP_OK) == DCP_OK)
  259.          return DCP_OK;
  260.       else
  261.          return DCP_FAILED;
  262.    } /* if ( eof ) */
  263.  
  264.    left = (short) s_pktsize;
  265.    op = packet;
  266.    sum = chksum;
  267.  
  268. /*--------------------------------------------------------------------*/
  269. /*                     Loop to fill up one packet                     */
  270. /*--------------------------------------------------------------------*/
  271.  
  272.    do {
  273.       ip = tbuf;
  274.       len = (short) sread(ip, 1, M_fPacketTimeout); /* single-byte reads for now */
  275.       if (len == 0) {
  276.          printmsg(0,"fgetpkt: Timeout after %d seconds", M_fPacketTimeout);
  277.          return DCP_FAILED;               /* Fail if timed out */
  278.       }
  279.       if ((*ip &= 0177) >= '\172') {
  280.          if (special) {
  281.             special = 0;
  282.             if (*ip++ != '\176')
  283.             {
  284.                printmsg(0,"fgetpkt: Did not expect character ^%c (x%02x)",
  285.                   (char) (*(ip-1) + 'A') , (short) *(ip-1));
  286.                goto dcorr;
  287.             }
  288.             len = 0;
  289.  
  290.             while (len < 5) {
  291.                i = (short) sread(&buf[len], 5 - len, M_fPacketTimeout);
  292.                if (i == 0) {
  293.                   printmsg(0,
  294.                      "fgetpkt: Timeout reading %d chars after %d seconds",
  295.                               5 - len, M_fPacketTimeout);
  296.                   goto dcorr;
  297.                }
  298.                len += i;
  299.             }
  300.  
  301.             printmsg(6, "fgetpkt: buf=|%.*s|", len , packet);
  302.             if (buf[4] != '\r')
  303.             {
  304.                printmsg(0,
  305.                   "fgetpkt: error: Expected carriage return, "
  306.                    "not %s%c (x%02x)",
  307.                   (buf[4] < ' ') ? "^" : "" ,
  308.                   (char) (buf[4] + ((buf[4] < ' ') ? 'A' : 0)),
  309.                   (short) buf[4]);
  310.                goto dcorr;
  311.             }
  312.             sscanf(buf, "%4x", &chksum);
  313.             *bytes = (short) (op - packet);
  314.             if (chksum == sum) {
  315.                eof = TRUE;
  316.                printmsg(6, "fgetpkt: data=|%.*s|", *bytes , packet);
  317.                return DCP_OK;
  318.             } else {
  319.                printmsg(0, "fgetpkt: Checksum mismatch, told %04x, calc %04x",
  320.                             chksum, sum);
  321.                fsendresp(DCP_RETRY);
  322.                return DCP_RETRY;
  323.             }
  324.          }
  325.          special = *ip++;
  326.       } else {
  327.          if (*ip < '\040') {
  328.             printmsg(0,"fgetpkt: error: got control character ^%c (%x)",
  329.                   (char) (*ip + 'A') , (short) *ip);
  330.             goto dcorr;
  331.          }
  332.  
  333.          switch (special) {
  334.             case 0:
  335.                c = (char) (*ip++);
  336.                break;
  337.             case '\172':
  338.                c = (char) (*ip++ - 0100);
  339.                break;
  340.             case '\173':
  341.                c = (char) (*ip++ + 0100);
  342.                break;
  343.             case '\174':
  344.                c = (char) (*ip++ + 0100);
  345.                break;
  346.             case '\175':
  347.                c = (char) (*ip++ + 0200);
  348.                break;
  349.             case '\176':
  350.                c = (char) (*ip++ + 0300);
  351.                break;
  352.             default:
  353.                printmsg(0,"fgetpkt: Invalid special chracter 0x%2x",
  354.                           (short) special );
  355.                panic();
  356.                c = '\0';
  357.          }
  358.  
  359.          *op++ = c;
  360.          left --;
  361.          if (sum & 0x8000) {
  362.             sum <<= 1;
  363.             sum++;
  364.          } else
  365.             sum <<= 1;
  366.          sum += (short) (c & 0377);
  367.          sum &= 0xffff;
  368.          special = 0;
  369.       }
  370.    } while (left > 0);
  371.  
  372. /*--------------------------------------------------------------------*/
  373. /*            The packet is full of data, return to caller            */
  374. /*--------------------------------------------------------------------*/
  375.  
  376.    *bytes = (short) s_pktsize;
  377.    printmsg(6, "fgetpkt: data=|%.*s|", *bytes , packet);
  378.    chksum = sum;
  379.    return DCP_OK;
  380.  
  381. /*--------------------------------------------------------------------*/
  382. /*            The data is corrupt; flush the incoming file            */
  383. /*--------------------------------------------------------------------*/
  384.  
  385. dcorr:
  386.    printmsg (0, "Data corrupted, skipping to EOF");
  387.  
  388.    len = 1;
  389.    while (len)
  390.       len = (short) sread(packet, 1, M_fPacketTimeout);
  391.  
  392.    fsendresp(DCP_RETRY);
  393.    return DCP_RETRY;
  394. } /* fgetpkt */
  395.  
  396. /*--------------------------------------------------------------------*/
  397. /*    f s e n d p k t                                                 */
  398. /*                                                                    */
  399. /*    Send an "f" protocol packet to the other system                 */
  400. /*--------------------------------------------------------------------*/
  401.  
  402. short fsendpkt(char *ip, short len)
  403. {
  404.    char *op;
  405.    short sum, nl;
  406.    short ret;
  407.    char obuf[MAXPACK * 2];
  408.    op = obuf;
  409.    nl = 0;
  410.    sum = chksum;
  411.    if (len == 0)
  412.    {
  413.       printmsg(0,"fsendpkt: Internal error: zero length for packet");
  414.       return DCP_FAILED;
  415.    }
  416.    do {
  417.       if (sum & 0x8000) {
  418.          sum <<= 1;
  419.          sum++;
  420.       } else
  421.          sum <<= 1;
  422.       sum += (short) (*ip & 0377);
  423.       sum &= 0xffff;
  424.       if (*ip & 0200) {
  425.          *ip &= 0177;
  426.          if (*ip < 040) {
  427.             *op++ = '\174';
  428.             *op++ = (char) (*ip++ + 0100);
  429.          } else
  430.          if (*ip <= 0171) {
  431.             *op++ = '\175';
  432.             *op++ = *ip++;
  433.          }
  434.          else {
  435.             *op++ = '\176';
  436.             *op++ = (char) (*ip++ - 0100);
  437.          }
  438.          nl += 2;
  439.       } else {
  440.          if (*ip < 040) {
  441.             *op++ = '\172';
  442.             *op++ = (char) (*ip++ + 0100);
  443.             nl += 2;
  444.          } else
  445.          if (*ip <= 0171) {
  446.             *op++ = *ip++;
  447.             nl++;
  448.          } else {
  449.             *op++ = '\173';
  450.             *op++ = (char) (*ip++ - 0100);
  451.             nl += 2;
  452.          }
  453.       }
  454.    } while (--len > 0);
  455.    chksum = sum;
  456.    ret = (short) swrite(obuf, nl);
  457.    if ( ret == nl )
  458.       return DCP_OK;
  459.    else
  460.       return DCP_FAILED;
  461. } /* fsendpkt */
  462.  
  463. /*--------------------------------------------------------------------*/
  464. /*    f f i l e p k t                                                 */
  465. /*                                                                    */
  466. /*    Prepare for processing an "f" procotol file transfer            */
  467. /*--------------------------------------------------------------------*/
  468.  
  469. short ffilepkt( void)
  470. {
  471.    chksum = 0xffff;
  472.    printmsg(3,"ffilepkt: Checksum reset");
  473.    return DCP_OK;
  474. } /* ffilepkt */
  475.  
  476. /*--------------------------------------------------------------------*/
  477. /*    f e o f                                                         */
  478. /*                                                                    */
  479. /*    Transmit "f" protocol end of file to the other system           */
  480. /*--------------------------------------------------------------------*/
  481.  
  482. short feofpkt( void )
  483. {
  484.    char ibuf[MAXMSGLEN];
  485.  
  486. /*--------------------------------------------------------------------*/
  487. /*               Transmit EOF with an attached checksum               */
  488. /*--------------------------------------------------------------------*/
  489.  
  490.    printmsg(2,"feofpkt: sending EOF");
  491.    sprintf(ibuf, "\176\176%04x", chksum);
  492.    printmsg(2,"--> %s", ibuf);
  493.    fwrmsg(ibuf);
  494.  
  495. /*--------------------------------------------------------------------*/
  496. /*                 Now get the response and report it                 */
  497. /*--------------------------------------------------------------------*/
  498.  
  499.    if (frdmsg(ibuf) == DCP_FAILED)
  500.       return DCP_FAILED;
  501.  
  502.    printmsg(2,"<-- %s",ibuf);
  503.  
  504. /*--------------------------------------------------------------------*/
  505. /*              Determine our next step from the result               */
  506. /*--------------------------------------------------------------------*/
  507.  
  508.    switch(*ibuf)
  509.    {
  510.       case 'R':
  511.          return DCP_RETRY;
  512.  
  513.       case 'G':
  514.          return DCP_OK;
  515.  
  516.       default:
  517.          return DCP_FAILED;
  518.  
  519.    } /* switch */
  520.  
  521. } /* feofpkt */
  522.  
  523. /*--------------------------------------------------------------------*/
  524. /*    f s e n d r e s p                                               */
  525. /*                                                                    */
  526. /*    Send result to a file transfer to other host                    */
  527. /*--------------------------------------------------------------------*/
  528.  
  529. static short fsendresp(short state)
  530. {
  531.    char *s;
  532.    switch (state)
  533.    {
  534.       case DCP_OK:
  535.          s = "G";
  536.          break;
  537.  
  538.       case DCP_RETRY:
  539.          s = "R";
  540.          break;
  541.  
  542.       default:
  543.          s = "Q";
  544.          break;
  545.    }
  546.  
  547.    printmsg(2,"--> %s", s);
  548.    return fwrmsg(s);
  549.  
  550. } /* fsendresp */
  551.