home *** CD-ROM | disk | FTP | other *** search
- /* $Header: fio.c,v 1.20 85/04/30 12:57:32 rick Exp $ */
- /* %M% %I% %E% (Mathematisch Centrum) */
-
- /*--------------------------------------------------------------------*/
- /* Flow control ("f") protocol. */
- /* */
- /* This protocol relies on flow control of the data stream. It */
- /* is meant for working over links that can (almost) be */
- /* guaranteed to be errorfree, specifically X.25/PAD links. A */
- /* sumcheck is carried out over a whole file only. If a */
- /* transport fails the receiver can request retransmission(s). */
- /* This protocol uses a 7-bit datapath only, so it can be used */
- /* on links that are not 8-bit transparent. */
- /* */
- /* When using this protocol with an X.25 PAD: Although this */
- /* protocol uses no control chars except CR, control chars NULL */
- /* and ^P are used before this protocol is started; since ^P is */
- /* the default char for accessing PAD X.28 command mode, be */
- /* sure to disable that access (PAD par 1). Also make sure */
- /* both flow control pars (5 and 12) are set. The CR used in */
- /* this proto is meant to trigger packet transmission, hence */
- /* par 3 should be set to 2; a good value for the Idle Timer */
- /* (par 4) is 10. All other pars should be set to 0. */
- /* */
- /* Normally a calling site will take care of setting the local */
- /* PAD pars via an X.28 command and those of the remote PAD via */
- /* an X.29 command, unless the remote site has a special */
- /* channel assigned for this protocol with the proper par */
- /* settings. */
- /* */
- /* Author: Piet Beertema, CWI, Amsterdam, Sep 1984 */
- /* */
- /* Adapted to uupc 3.0 and THINK C 4.0 by Dave Platt, Jul 1991 */
- /*--------------------------------------------------------------------*/
-
- /*--------------------------------------------------------------------*/
- /* System include files */
- /*--------------------------------------------------------------------*/
-
- #include <stdio.h>
- #include <time.h>
- #include <string.h>
-
- /*--------------------------------------------------------------------*/
- /* UUPC/extended include files */
- /*--------------------------------------------------------------------*/
-
- #include "lib.h"
- #include "dcp.h"
- #include "dcpfpkt.h"
- #include "dcpsys.h"
- #include "hostable.h"
- #include "security.h"
- #include "ssleep.h"
- #include "ulib.h"
-
- /*--------------------------------------------------------------------*/
- /* Defines */
- /*--------------------------------------------------------------------*/
-
- #define PKTSIZE 64
-
- #ifndef MAXMSGLEN
- #define MAXMSGLEN BUFSIZ
- #endif MAXMSGLEN
-
- /*--------------------------------------------------------------------*/
- /* Internal function prototypes */
- /*--------------------------------------------------------------------*/
-
- static int fsendresp(int state);
-
- /*--------------------------------------------------------------------*/
- /* Global variables */
- /*--------------------------------------------------------------------*/
-
- static int chksum;
-
- /*--------------------------------------------------------------------*/
- /* f o p e n p k */
- /* */
- /* Open "f" protocol to other system */
- /*--------------------------------------------------------------------*/
-
- int fopenpk()
- {
- flowcontrol(TRUE);
- pktsize = PKTSIZE;
- ssleep(2); /* Give peer time to perform corresponding port setup */
- return OK;
- } /* fopenpk */
-
- /*--------------------------------------------------------------------*/
- /* f c l o s e p k */
- /* */
- /* Shutdown "f" procotol with other system */
- /*--------------------------------------------------------------------*/
-
- fclosepk()
- {
- flowcontrol(FALSE);
- return OK;
- } /* fclosepk */
-
- /*--------------------------------------------------------------------*/
- /* f w r m s g */
- /* */
- /* Send a control message to remote system with "f" procotol */
- /*--------------------------------------------------------------------*/
-
- int fwrmsg(char *str)
- {
- char bufr[MAXMSGLEN];
- char *s = bufr;
-
- while (*str)
- *s++ = *str++;
- if (*(s-1) == '\n')
- s--;
- *s++ = '\r';
- (void) swrite(bufr, s - bufr);
- return OK;
- } /* fwrmsg */
-
- /*--------------------------------------------------------------------*/
- /* f r d m s g */
- /* */
- /* Read a control message from remote host with "f" protocol */
- /*--------------------------------------------------------------------*/
-
- int frdmsg(char *str)
- {
- char *smax;
- char *s = str;
-
- smax = s + MAXPACK - 1;
- for (;;) {
- if (sread(s, 1, PacketTimeout) <= 0)
- {
- printmsg(0,"frdmsg: timeout reading message");
- *s++ = '\0';
- goto msgerr;
- }
- if (*s == '\r')
- break;
- if (*s < ' ')
- continue;
- if (s++ >= smax)
- {
- printmsg(0,"frdmsg: buffer overflow");
- *--s = '\0';
- goto msgerr;
- } /* if (s++ >= smax) */
- }
- *s = '\0';
- return OK;
-
- msgerr:
- printmsg(0,"frdmsg: Message received \"%s\"", str);
- return FAILED;
- } /* frdmsg */
-
- /*--------------------------------------------------------------------*/
- /* f g e t p k t */
- /* */
- /* Receive an "f" protocol packet of data from the other system */
- /*--------------------------------------------------------------------*/
-
- int fgetpkt(char *packet, int *bytes)
- {
- char *op, c, *ip;
- int sum, len, left;
- char buf[5], tbuf[1];
- int i;
- static char special = 0;
- static boolean eof = FALSE;
-
- /*--------------------------------------------------------------------*/
- /* Handle EOF on previous call */
- /*--------------------------------------------------------------------*/
-
- if ( eof )
- {
- eof = FALSE;
- printmsg(0,"fgetpkt: EOF from other host");
- *bytes = 0;
- if (fsendresp(OK) == OK)
- return OK;
- else
- return FAILED;
- } /* if ( eof ) */
-
- left = pktsize;
- op = packet;
- sum = chksum;
-
- /*--------------------------------------------------------------------*/
- /* Loop to fill up one packet */
- /*--------------------------------------------------------------------*/
-
- do {
- ip = tbuf;
- len = sread(ip, 1, PacketTimeout); /* single-byte reads for now */
- if (len == 0) {
- printmsg(0,"fgetpkt: Timeout after %d seconds", PacketTimeout);
- return FAILED; /* Fail if timed out */
- }
- if ((*ip &= 0177) >= '\172') {
- if (special) {
- special = 0;
- if (*ip++ != '\176')
- {
- printmsg(0,"fgetpkt: error: Did not expect character\
- ^%c (x%02x)",
- (char) (*(ip-1) + 'A') , (int) *(ip-1));
- goto dcorr;
- }
- len = 0;
-
- while (len < 5) {
- i = sread(&buf[len], 5 - len, PacketTimeout);
- if (i == 0) {
- printmsg(0,
- "fgetpkt: Timeout reading %d chars after %d seconds",
- 5 - len, PacketTimeout);
- goto dcorr;
- }
- len += i;
- }
-
- printmsg(6, "fgetpkt: buf=|%.*s|", len , packet);
- if (buf[4] != '\r')
- {
- printmsg(0,"fgetpkt: error: Expected carriage return, \
- not %s%c (x%02x)",
- (buf[4] < ' ') ? "^" : "" ,
- (char) (buf[4] + ((buf[4] < ' ') ? 'A' : 0)),
- (int) buf[4]);
- goto dcorr;
- }
- sscanf(buf, "%4x", &chksum);
- *bytes = op - packet;
- if (chksum == sum) {
- eof = TRUE;
- printmsg(6, "fgetpkt: data=|%.*s|", *bytes , packet);
- return OK;
- } else {
- printmsg(0, "fgetpkt: Checksum mismatch, told %04x, calc %04x",
- chksum, sum);
- fsendresp(RETRY);
- return RETRY;
- }
- }
- special = *ip++;
- } else {
- if (*ip < '\040') {
- printmsg(0,"fgetpkt: error: got control character ^%c (%x)",
- (char) (*ip + 'A') , (int) *ip);
- goto dcorr;
- }
-
- switch (special) {
- case 0:
- c = (char) (*ip++);
- break;
- case '\172':
- c = (char) (*ip++ - 0100);
- break;
- case '\173':
- c = (char) (*ip++ + 0100);
- break;
- case '\174':
- c = (char) (*ip++ + 0100);
- break;
- case '\175':
- c = (char) (*ip++ + 0200);
- break;
- case '\176':
- c = (char) (*ip++ + 0300);
- break;
- }
-
- *op++ = c;
- left --;
- if (sum & 0x8000) {
- sum <<= 1;
- sum++;
- } else
- sum <<= 1;
- sum += c & 0377;
- sum &= 0xffff;
- special = 0;
- }
- } while (left > 0);
-
- /*--------------------------------------------------------------------*/
- /* The packet is full of data, return to caller */
- /*--------------------------------------------------------------------*/
-
- *bytes = pktsize;
- printmsg(6, "fgetpkt: data=|%.*s|", *bytes , packet);
- chksum = sum;
- return OK;
-
- /*--------------------------------------------------------------------*/
- /* The data is corrupt; flush the incoming file */
- /*--------------------------------------------------------------------*/
-
- dcorr:
- printmsg (0, "Data corrupted, skipping to EOF");
-
- len = 1;
- while (len)
- len = sread(packet, 1, PacketTimeout);
-
- fsendresp(RETRY);
- return RETRY;
- } /* fgetpkt */
-
- /*--------------------------------------------------------------------*/
- /* f s e n d p k t */
- /* */
- /* Send an "f" protocol packet to the other system */
- /*--------------------------------------------------------------------*/
-
- fsendpkt(char *ip, int len)
- {
- char *op;
- int sum, nl;
- int ret;
- char obuf[MAXPACK * 2];
- op = obuf;
- nl = 0;
- sum = chksum;
- if (len == 0)
- {
- printmsg(0,"fsendpkt: Internal error: zero length for packet");
- return FAILED;
- }
- do {
- if (sum & 0x8000) {
- sum <<= 1;
- sum++;
- } else
- sum <<= 1;
- sum += *ip & 0377;
- sum &= 0xffff;
- if (*ip & 0200) {
- *ip &= 0177;
- if (*ip < 040) {
- *op++ = '\174';
- *op++ = (char) (*ip++ + 0100);
- } else
- if (*ip <= 0171) {
- *op++ = '\175';
- *op++ = *ip++;
- }
- else {
- *op++ = '\176';
- *op++ = (char) (*ip++ - 0100);
- }
- nl += 2;
- } else {
- if (*ip < 040) {
- *op++ = '\172';
- *op++ = (char) (*ip++ + 0100);
- nl += 2;
- } else
- if (*ip <= 0171) {
- *op++ = *ip++;
- nl++;
- } else {
- *op++ = '\173';
- *op++ = (char) (*ip++ - 0100);
- nl += 2;
- }
- }
- } while (--len > 0);
- chksum = sum;
- ret = swrite(obuf, nl);
- if ( ret == nl )
- return OK;
- else
- return FAILED;
- } /* fsendpkt */
-
- /*--------------------------------------------------------------------*/
- /* f f i l e p k t */
- /* */
- /* Prepare for processing an "f" procotol file transfer */
- /*--------------------------------------------------------------------*/
-
- int ffilepkt( void)
- {
- chksum = 0xffff;
- printmsg(3,"ffilepkt: Checksum reset");
- return OK;
- } /* ffilepkt */
-
- /*--------------------------------------------------------------------*/
- /* f e o f */
- /* */
- /* Transmit "f" protocol end of file to the other system */
- /*--------------------------------------------------------------------*/
-
- int feofpkt( void )
- {
- char ibuf[MAXMSGLEN];
- printmsg(0,"feofpkt: sending EOF");
- sprintf(ibuf, "\176\176%04x", chksum);
- fwrmsg(ibuf);
- printmsg(2,"--> %s", ibuf);
-
- if (frdmsg(ibuf) == FAILED)
- return FAILED;
-
- printmsg(2,"<-- %s",ibuf);
-
- switch(*ibuf)
- {
- case 'R':
- return RETRY;
-
- case 'G':
- return OK;
-
- default:
- return FAILED;
-
- } /* switch */
-
- } /* feofpkt */
-
- /*--------------------------------------------------------------------*/
- /* f s e n d r e s p */
- /* */
- /* Send result to a file transfer to other host */
- /*--------------------------------------------------------------------*/
-
- static int fsendresp(int state)
- {
- char *s;
- switch (state)
- {
- case OK:
- s = "G";
- break;
-
- case RETRY:
- s = "R";
- break;
-
- default:
- s = "Q";
- break;
- }
-
- printmsg(2,"--> %s", s);
- return fwrmsg(s);
-
- } /* fsendresp */
-