[comp.mail.uucp] Descriptions needed of uucp protocols

jeh@simpact.uucp (Jamie Hanrahan, jeh@crash.cts.com) (09/08/89)

A long time ago in this newsgroup, a partial list of uucp protocols was
posted.  It included

	'f'	X.25 PAD protocol (source for this has been posted to the net;
		it assumes a 7-bit, error-free channel)
	'g'	regular packet protocol
	'x'	simple protocol (???)
	't'	written by Rick Adams, primarily for bsd/tcp-ip, usable for
		any error-free channel with its own flow control	
	'd'	similar to 't', written about the same time by the HDB/BNU
		people
	'k'	similar to 'f' for 7-bit in-band flow control channels

I want to add a few protocol options to DECUS uucp (uucp for VMS).  
From these sketchy descriptions, both t/d and k sound interesting.  (I need
'k' for dialup links over which xon/xoff flow control can't be disabled, and
I need 't' or 'd', or something similar, to run over DECnet.)  

Can anyone send me or provide pointers to descriptions of these?  (I could 
of course invent my own protocols, but I'd much rather not!) 

Please reply to me directly; I will post a summary of the replies.  Thank you.

	--- Jamie Hanrahan, Simpact Associates, San Diego CA
Chair, VMSnet [DECUS uucp] and Internals Working Groups, DECUS VAX Systems SIG 
Internet:  jeh@simpact.com, or if that fails, jeh@crash.cts.com
Uucp:  ...{crash,scubed,decwrl}!simpact!jeh

wswietse@lso.win.tue.nl (Wietse Venema) (09/12/89)

In article <358@simpact.uucp> jeh@simpact.uucp (Jamie Hanrahan, jeh@crash.cts.com) writes:
>A long time ago in this newsgroup, a partial list of uucp protocols was
>posted.  It included
>
>	'f'	X.25 PAD protocol (source for this has been posted to the net;
>		it assumes a 7-bit, error-free channel)
>	'g'	regular packet protocol
>	'x'	simple protocol (???)
>	't'	written by Rick Adams, primarily for bsd/tcp-ip, usable for
>		any error-free channel with its own flow control	
>	'd'	similar to 't', written about the same time by the HDB/BNU
>		people
>	'k'	similar to 'f' for 7-bit in-band flow control channels

Every now and then I see a reference to the 'k' protocol that I once
developed for our SYTEK local network. It was posted (May last year) to
comp.sources.misc as part of an ms-dos e-mail package. Since the
protocol-specific part of the source is quite small, I am posting it
here so that no-one has to download all the ms-dos cruft :-).

This code was used with "old" uucp; i.e. it was never tried with HDB.
In order to install, edit the protocol table in cntrl.c, compile these
source and link them with uucico.

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  kio.c kp.h kphys.c kpres.c kproto.ms ktrans.c
# Wrapped by wswietse@lso.win.tue.nl on Tue Sep 12 15:08:34 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f kio.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"kio.c\"
else
echo shar: Extracting \"kio.c\" \(4784 characters\)
sed "s/^X//" >kio.c <<'END_OF_kio.c'
X/*++
X/* NAME
X/*	kio 3
X/* SUMMARY
X/*	interface between uucico and k-protocol driver
X/* PACKAGE
X/*	uucp on the TUEnet
X/* SYNOPSIS
X/*	kturnon()
X/*
X/*	kwrmsg(type,str,fn)
X/*	char type, *str;
X/*	int fn;
X/*
X/*	krdmsg(str,fn)
X/*	char *str;
X/*	int fn;
X/*
X/*	krddata(fn,fp)
X/*	int fn;
X/*	FILE *fp;
X/*
X/*	kwrdata(fp,fn)
X/*	FILE *fp;
X/*	int fn;
X/*
X/*	kturnoff()
X/* IMPLICIT INPUTS
X/*	Ifn, Ofn, file descriptors
X/*	Debug, debugging level
X/* DESCRIPTION
X/*	The k protocol has been developed for the Sytek Localnet local area 
X/*	network at the Eindhoven University of Technology (THE).
X/*	Main features of this network are:
X/*
X/* .IP	o 
X/*	Network partners may talk at different baudrates. This implies
X/*	that the network does some buffering and that it needs flow control.
X/* .IP	o 
X/*	The network is normally not transparent for some control 
X/*	characters (XON,XOFF and locally-defined others), independent 
X/*	of the value of the eigth bit.
X/* .IP	o 
X/*	Some network stations are connected to telephone modems.
X/*
X/*	For these reasons, the k protocol must (i) rely on XON/XOFF flow 
X/*	control, (ii) be suitable for 7-bit data paths, (iii) avoid
X/*	sending of control characters and (iv) provide reliable operation
X/*	over dial-in and dial-out telephone lines.
X/*
X/*	Data are sent as checksummed 512-byte packets, terminated by an 
X/*	ASCII CR. Except for packet headers (^P), the k protocol only uses 
X/*	ASCII codes 040 through 0137. Three data bytes are expanded to four 
X/*	bytes upon transmission.
X/*	
X/*	The functions in kio.c form the interface between the uucico
X/*	controlling functions, and the k-protocol packet driver.
X/*
X/*	kturnon() sets the terminal line characteristics (XON/XOFF). Always
X/*	returns zero status.
X/*
X/*	krdmsg(), kwrmsg() exchange null-terminated strings.
X/*	Exit status zero, or FAIL.
X/*
X/*	krddata(), kwrdata() perform file i/o, and accounting. Exit status 
X/*	zero or FAIL.
X/*
X/*	kturnoff() sends a protocol abort sequence. Always returns zero 
X/*	status.
X/* FUNCTIONS AND MACROS
X/*	kread, kread, kwrite, kclose, k-protocol presentation layer 
X/* AUTHOR(S)
X/*	Wietse Venema
X/*	Eindhoven University of Technology
X/*	Department of Mathematics and Computer Science
X/*	Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
X/* CREATION DATE
X/*	Mon Feb  3 10:13:34 MET 1986
X/* LAST MODIFICATION
X/*	Mon Apr  4 23:42:46 MET 1988
X/* VERSION/RELEASE
X/*	2.4
X/*--*/
X
X#include "uucp.h"
X
X#define	BUFLEN	BUFSIZ
X
Xkturnon()
X{
X    kopen(Ifn);
X    return 0;
X}
X
X
Xkturnoff()
X{
X    kclose(Ofn);
X    return 0;
X}
X
X
Xkwrmsg(type,str,fn)
Xchar type,*str;
Xint fn;
X{
X    char bufr[BUFSIZ],*s;
X
X    bufr[0] = type;
X    s = &bufr[1];
X    while (*str)
X	*s++ = *str++;
X    *s = '\0';
X    if (*(--s) == '\n')
X	*s = '\0';
X    DEBUG(6," kwrmsg: \"%s\"\n",bufr);
X
X    return (kwrite(fn,bufr,strlen(bufr)+1) > 0 ? 0 : FAIL);
X}
X
X
Xkrdmsg(str,fn)
Xchar *str;
Xint fn;
X{
X    int len;
X
X    for (;;) {
X	if ((len = kread(fn,str,BUFSIZ)) == 0) {
X	    continue;
X	} else if (len > 0) {
X	    str[len] = 0;
X	    DEBUG(6," krdmsg: \"%s\"\n",str);
X	    str += len;
X	    if (str[-1] == '\0')
X		return 0;
X	} else {
X	    return FAIL;
X	}
X    }
X}
X
X
Xkwrdata(fp1,fn)
XFILE *fp1;
X{
X    char bufr[BUFLEN];
X    int len;
X    int ret;
X    time_t t1,t2;
X    long bytes;
X    char text[BUFSIZ];
X
X    ret = FAIL;
X    bytes = 0L;
X    time(&t1);
X    while ((len = fread(bufr,sizeof (char),BUFLEN,fp1)) > 0) {
X	bytes += len;
X	if (kwrblk(bufr,len,fn) != len)
X	    goto acct;
X	if (len != BUFLEN)
X	    break;
X    }
X    ret = kwrblk(bufr,0,fn);
Xacct:
X    time(&t2);
X    sprintf(text,ret == 0 ?
X    "sent data %ld bytes %ld secs" :
X    "send failed after %ld bytes",
X    bytes,t2 - t1);
X    DEBUG(1,"%s\n",text);
X    syslog(text);
X    sysacct(bytes,t2 - t1);
X    if (ret)
X	sysaccf(NULL);		/* force accounting */
X    return ret;
X}
X
X
Xkrddata(fn,fp2)
XFILE *fp2;
X{
X    int len,ret;
X    char bufr[BUFLEN];
X    time_t t1,t2;
X    long bytes;
X    char text[BUFSIZ];
X
X    ret = FAIL;
X    bytes = 0L;
X    time(&t1);
X    for (;;) {
X	len = krdblk(bufr,BUFLEN,fn);
X	if (len < 0)
X	    goto acct;
X	bytes += len;
X	if (fwrite(bufr,sizeof (char),len,fp2) != len)
X	    goto acct;
X	if (len < BUFLEN)
X	    break;
X    }
X    ret = 0;
Xacct:
X    time(&t2);
X    sprintf(text,ret == 0 ? 
X    "received data %ld bytes %ld secs" :
X    "receive failed after %ld bytes",
X    bytes,t2 - t1);
X    DEBUG(1,"%s\n",text);
X    syslog(text);
X    sysacct(bytes,t2 - t1);
X    if (ret)
X	sysaccf(NULL);		/* force accounting */
X    return ret;
X}
X
X
Xkrdblk(blk,len, fn)
Xchar *blk;
Xint len,fn;
X{
X    int i,ret;
X
X    for (i = 0; i < len; i += ret) {
X	if ((ret = kread(fn,blk,len-i)) == 0) {
X	    break;
X	} else if (ret > 0) {
X	    blk += ret;
X	} else {
X	    return FAIL;
X	}
X    }
X    return i;
X}
X
X
Xkwrblk(blk,len,fn)
Xchar *blk;
Xint len,fn;
X{
X    return kwrite(fn,blk,len);
X}
END_OF_kio.c
if test 4784 -ne `wc -c <kio.c`; then
    echo shar: \"kio.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f kp.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"kp.h\"
else
echo shar: Extracting \"kp.h\" \(2264 characters\)
sed "s/^X//" >kp.h <<'END_OF_kp.h'
X/*++
X/* NAME
X/*	kp 5
X/* SUMMARY
X/*	definitions file for k protocol
X/* PACKAGE
X/*	uucp across the thenet
X/* SYNOPSIS
X/*	#include "kp.h"
X/* DESCRIPTION
X/*	The following definitions are made in the file kp.h:
X/* .nf
X
X/* /* Need stderr definition from stdio.h */
X
X#include "stdio.h"
X
X/* /* Symbol Definitions */
X 
X#define	PACKSIZ     256     /* Packet size sent by this uucico */
X#define MAXPACKSIZ  1024    /* Maximum packet size I can receive */
X#define SOH         16      /* Start of header */
X#define CR          13      /* ASCII Carriage Return */
X#define	SP          32      /* ASCII Blank */
X 
X#define MAXTRY      10      /* Times to retry a packet */
X
X/* /* 5 secs timeout interval turns out to be too short, when THEnet is busy */
X 
X#define TIMEOUT     10      /* Seconds after which I should be timed out */
X 
X#define TRUE         1      /* Boolean constants */
X#define FALSE        0
X
X#define	NULLP (char*)0      /* NULL pointer */
X#define	FAIL        -1      /* Read/write return value in case of error */
X#define	TIME        -2      /* Receive packet return status if timed out */
X 
X#define	OUT          6      /* Nr. of data bits per char in packet */
X#define	IN           8      /* Nr. of data bits per byte */
X#define	STEP         2      /* Difference between previous two */
X#define	MASK       077      /* Mask for number of data bits in packet */
X
X/* /* Macro Definitions */
X 
X#define tosix(ch)  (((ch) & MASK) + SP)
X#define unsix(ch)  (((ch) - SP) & MASK)
X
X#define tochar(ch)  ((ch) + SP)
X#define unchar(ch)  ((ch) - SP)
X
X/* /* intercept system calls in case of non-unix operating systems */
X
X#ifndef	unix
X
X#define	read		xread
X#define	write		xwrite
X#define	alarm(x)	/* nothing */
X#define	signal(x,y)	/* nothing */
X#define	DEBUG(x,y,z)	if (dflag >= x) printf(y,z)
X
Xextern int dflag;
X
X#else
X
X#define DEBUG(l,f,s) if (Debug >= l) fprintf(stderr,f,s)
X
X/* /* Declarations */
X
Xextern int Debug;           /* Debugging level */
X
X#endif
X/* AUTHOR(S)
X/*	Wietse Venema
X/*	Eindhoven University of Technology
X/*	Department of Mathematics and Computer Science
X/*	Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
X/* CREATION DATE
X/*	Mon Feb  3 22:14:23 MET 1986
X/* LAST MODIFICATION
X/*	Mon Apr  4 23:43:00 MET 1988
X/* VERSION/RELEASE
X/*	2.4
X/*--*/
END_OF_kp.h
if test 2264 -ne `wc -c <kp.h`; then
    echo shar: \"kp.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f kphys.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"kphys.c\"
else
echo shar: Extracting \"kphys.c\" \(7524 characters\)
sed "s/^X//" >kphys.c <<'END_OF_kphys.c'
X/*++
X/* NAME
X/*      kphys 3
X/* SUMMARY
X/*      k protocol packet exchange
X/* PACKAGE
X/*      uucp across the TUEnet
X/* SYNOPSIS
X/*      #include "kp.h"
X/*
X/*      kspack(fd,type,num,size,data) 
X/*      int fd, num, size;
X/*      char type, data[MAXPACKSIZ];
X/*
X/*      krpack(fd,num,size,data)
X/*      int fd, *num, *size;
X/*      char data[MAXPACKSIZ];
X/* DESCRIPTION
X/*      The functions in this file take care of data framing and verification. 
X/*
X/*      Kspack() sends a packet of the specified type and number,
X/*      and with len data bytes.
X/*
X/*      Krpack() tries to receive a packet and returns: the packet type plus
X/*      size and data, or TIME (no packet) or FAIL (bad checksum).
X/*
X/*      The data format has been derived from kermit implementations:
X/*
X/* .nf
X/* .in +5
X/*      SOH     packet header, ASCII control-P
X/*      len     (size of data, low 6 bits) + 32
X/*      len     (size of data, high 6 bits) + 32
X/*      num     (packet number mod 64) + 32
X/*      type    packet type
X/*      check   one-byte type-1 kermit checksum
X/*
X/*      The header is followed by checksummed data if len >0:
X/*
X/* .nf
X/* .in +5
X/*      data    len data bytes
X/*      check1  (upper 2 bits of type-3 kermit 16-bit checksum) + 32
X/*      check2  (middle 6 bits of type-3 kermit 16-bit checksum) + 32
X/*      check3  (lower 6 bits of type-3 kermit 16-bit checksum) + 32
X/*
X/*      Every packet is followed by an ASCII carriage return, which is
X/*      ignored upon reception of a packet. It prevents timeout errors
X/*      when one byte gets lost (the most common case).
X/* BUGS
X/*      It is yet another convention for data framing.
X/* AUTHOR(S)
X/*      Wietse Venema
X/*      Eindhoven University of Technology
X/*      Department of Mathematics and Computer Science
X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
X/* CREATION DATE
X/*      Mon Feb  3 13:38:14 MET 1986
X/* LAST MODIFICATION
X/*	Mon Apr  4 23:43:13 MET 1988
X/* VERSION/RELEASE
X/*	1.5
X/*--*/
X
X#include <signal.h>
X#include <setjmp.h>
X#include "kp.h"
X
X#define READS(fd,ch)    {if (read(fd,&ch,1) < 0) clkint(); if ((ch &= 0177) == SOH) goto SYNC;}
X
Xjmp_buf env;                /* Environment ptr for timeout longjump */
X
Xclkint()                                /* Timer interrupt handler */
X{
X    longjmp(env,TRUE);                  /* Tell krpack to give up */
X}
X
Xkspack(fd,type,num,len,data)
Xint fd;
Xchar type, *data;
Xint num, len;
X{
X    char chksum, header[6], chk[3];     /* Checksums, header */
X
X    DEBUG(7,"xmt: type %c\n",type);
X    if (len > 0)
X	DEBUG(7,"xmt: data %d\n",len);
X
X    header[0] = SOH;                    /* Packet marker (SOH) */
X    header[1] = tosix(len);             /* Send the character count */
X    chksum    = header[1];              /* Initialize the checksum */
X    header[2] = tosix(len>>OUT);        /* Send the character count */
X    chksum   += header[2];              /* Update checksum */
X    header[3] = tochar(num);            /* Packet number */
X    chksum   += header[3];              /* Update checksum */
X    header[4] = type;                   /* Packet type */
X    chksum   += header[4];              /* Update checksum */
X    chksum    = (((chksum&0300) >> 6)+chksum)&077; /* Compute header checksum */
X    header[5] = tochar(chksum);         /* Put it in the packet */
X    write(fd,header,6);                /* Send the header */
X
X    if (len > 0) {                      /* Make data packet */
X	write(fd,data,len);           /* Send data */
X	chk3(data,len,chk);           /* Compute 16-bit checksum */
X	write(fd,chk,3);              /* Send checksum */
X    }
X    write(fd,"\r",1);                   /* Extra-packet line terminator */
X}
X
Xkrpack(fd,num,len,data)
Xint fd;
Xint *num;                               /* Packet number */
Xint *len;                               /* Packet length */
Xchar *data;                             /* Packet data */
X{
X    int i;                              /* Data character number, loop exit */
X    char t,                             /* Current input character */
X    type,                           /* Packet type */
X    rchk[3],                        /* Data checksum from host */
X    cchk[3],                        /* Data checksum computed here */
X    cchksum,                        /* Our (computed) checksum */
X    rchksum;                        /* Header checksum from other host */
X
X    if (setjmp(env)) {
X	DEBUG(7,"rcv: timed out\n","");
X	return TIME;                    /* Timed out */
X    }
X    signal(SIGALRM,clkint);             /* Setup the timeout */
X    alarm(TIMEOUT);
X
X    for (;;)                            /* Wait for packet header */
X	READS(fd,t);
XSYNC:                                   /* Got SOH */
X    alarm(TIMEOUT);
X    DEBUG(7,"rcv: found sync\n","");
X    READS(fd,t);                        /* Get character */
X    cchksum = t;                        /* Start the checksum */
X    *len = unchar(t);                   /* Character count, low six bits */
X
X    READS(fd,t);                        /* Get character */
X    cchksum += t;                       /* Update checksum */
X    *len += (unchar(t)<<OUT);           /* Character count, high six bits */
X
X    READS(fd,t);                        /* Get character */
X    cchksum += t;                       /* Update checksum */
X    *num = unchar(t);                   /* Packet number */
X
X    READS(fd,t);                        /* Get character */
X    cchksum += t;                       /* Update checksum */
X    type = t;                           /* Packet type */
X
X    READS(fd,t);                        /* Get header checksum */
X    rchksum = unchar(t);                /* Convert to numeric */
X    /* Fold in bits 7,8 to compute */
X    cchksum = (((cchksum&0300) >> 6)+cchksum)&077; /* header checksum */
X
X    if (cchksum != rchksum) {
X	DEBUG(7,"rcv: bad header\n","");
X	alarm(0);                       /* Disable the timer interrupt */
X	return FAIL;
X    } 
X    DEBUG(7,"rcv: type %c\n",type);
X
X    if ((*len > 0) && (data != NULLP))
X    {
X	for (i=0; i<*len; i++)          /* The data itself, if any */
X	{                               /* Loop for character count */
X	    READS(fd,t);                /* Get character */
X	    data[i] = t;                /* Keep data */
X	}
X
X	for (i=0; i<3; i++)             /* 16-bit CRC checksum */
X	{
X	    READS(fd,t);                /* Get character */
X	    rchk[i] = t;                /* Keep data */
X	}
X
X	chk3(data,*len,cchk);           /* Compute CRC */
X	if (strncmp(rchk,cchk,3)) {     /* Check with received CRC */
X	    DEBUG(7,"rcv: bad data\n","");
X	    alarm(0);                   /* Disable the timer interrupt */
X	    return FAIL;
X	}
X	DEBUG(7,"rcv: data %d\n",*len);
X    }
X    alarm(0);				/* Disable the timer interrupt */
X    return(type);                       /* All OK, return packet type */
X}
X
X/*  C H K 3  --  Compute a type-3 Kermit block check.  */
X/*
XCalculate the 16-bit CRC of a string using a byte-oriented
Xtableless algorithm invented by Andy Lowry (Columbia University).  The
Xmagic number 010201 is derived from the CRC-CCITT polynomial x^16+x^12+x^5+1.
X*/
Xstatic chk3(s,len,chk) 
Xchar *s, *chk; 
Xint len; 
X{
X    unsigned int c, q;
X    long crc = 0;
X
X    while (len--) {
X	c = *s++;
X	q = (crc ^ c) & 017;            /* Low-order nibble */
X	crc = (crc >> 4) ^ (q * 010201);
X	q = (crc ^ (c >> 4)) & 017;     /* High order nibble */
X	crc = (crc >> 4) ^ (q * 010201);
X    }
X    *chk++ = tochar(((unsigned)(crc & 0170000)) >> 12);
X    *chk++ = tochar((crc & 07700) >> 6);
X    *chk++ = tochar(crc & 077);
X}
END_OF_kphys.c
if test 7524 -ne `wc -c <kphys.c`; then
    echo shar: \"kphys.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f kpres.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"kpres.c\"
else
echo shar: Extracting \"kpres.c\" \(4951 characters\)
sed "s/^X//" >kpres.c <<'END_OF_kpres.c'
X/*++
X/* NAME
X/*	kpres
X/* SUMMARY
X/*	k-protocol presentation layer
X/* PACKAGE
X/*	uucp across thenet
X/* SYNOPSIS
X/*	#include "kp.h"
X/*
X/*	kopen(fd)
X/*	int fd;
X/*
X/*	kwrite(fd,buf,len)
X/*	int fd,len;
X/*	char *buf;
X/*
X/*	kread(fd,buf,len)
X/*	int fd,len;
X/*	char *buf;
X/*
X/*	kclose(fd)
X/*	int fd;
X/* DESCRIPTION
X/*	This section contains functions that imitate standard unix
X/*	unbuffered i/o facilities. A status code of FAIL is returned when
X/*	the network partner wants to terminate the protocol, or when the
X/*	the transmission error rate is excessive.
X/*
X/*	Eight-bit data bytes are transported as harmless six-bit data bytes
X/*	in the ASCII range 32 through 95. This introduces an overhead of 33%.
X/*	For textfiles, this is hardly worse than kermit (typical overhead 
X/*	10 %). For binary files the overhead is much less than with kermit 
X/*	(typical overhead 60%).
X/*
X/*	Kopen() sets up the terminal characteristics of the specified file
X/*	descriptors (no echo, raw, tandem). Always returns zero status.
X/*
X/*	Kwrite() attempts to send the bytes in buf. A zero-length buffer 
X/*	should be written to indicate an end-of-file condition. Return status: 
X/*	the number of bytes requested, or FAIL.
X/*
X/*	Kread() attempts to read the requested number of bytes. Status code:
X/*	the number of bytes actually read, or FAIL. A read of zero bytes
X/*	normally indicates an end-of-file condition (see kwrite).
X/*
X/*	Kclose() sends a protocol abort sequence to the network partner.
X/*	This function should be called to terminate the k protocol driver
X/*	at the other end, or to confirm reception of a protocol abort sequence.
X/*	Kclose always returns zero exit status.
X/*
X/*	The function kfail() is called by the strategy layer functions to 
X/*	indicate protocol failure or termination.
X/* FUNCTIONS AND MACROS
X/*	kwproto, krproto, kclsproto
X/* BUGS
X/*	Zero byte read/writes are a clumsy way to handle end-of-files. 
X/*	They have been implemented for the sake of compatibility with uucico.
X/* AUTHOR(S)
X/*	Wietse Venema
X/*	Eindhoven University of Technology
X/*	Department of Mathematics and Computer Science
X/*	Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
X/* CREATION DATE
X/*	Mon Feb  3 11:14:13 MET 1986
X/* LAST MODIFICATION
X/*	Mon Apr  4 23:43:28 MET 1988
X/* VERSION/RELEASE
X/*	1.3
X/*--*/
X
X#ifdef unix
X# ifdef	SIII
X#   include <termio.h>
X# else
X#   include <sgtty.h>
X# endif
X#endif
X#include <setjmp.h>
X#include "kp.h"
X
Xstatic jmp_buf Failbuf;
X
Xkfail()
X{
X    longjmp(Failbuf,TRUE);
X}
X
Xkopen(fd)
Xint fd;
X{
X#ifdef unix
X# ifdef SIII
X    struct termio ttymode;
X
X    ioctl(fd,TCGETA,&ttymode);
X    ttymode.c_iflag = IXOFF|IXON|ISTRIP;
X    ttymode.c_cc[VMIN] = 1;
X    ttymode.c_cc[VTIME] = 0;
X    ioctl(fd,TCSETA,&ttymode);
X# else
X    struct sgttyb ttymode;
X
X    gtty(fd,&ttymode);
X    ttymode.sg_flags |= (TANDEM|RAW);
X    ttymode.sg_flags &= ~(ECHO|CBREAK);
X    stty(fd,&ttymode);
X# endif
X#else
X    xioctl(1);
X#endif
X    return 0;
X}
X
Xkwrite(fd,buf,len)
Xint fd;
Xregister char *buf;
Xregister int len;
X{
X    static char  packbuf[MAXPACKSIZ];
X    static char *packptr = packbuf;
X    register int c,i,rest,shift;
X
X    /* set error trap */
X
X    if (setjmp(Failbuf))
X	return FAIL;
X
X    /* if 'end of data' send null packet */
X
X    if (len <= 0) {
X	kwproto(fd,NULLP,0);
X	return 0;
X
X    /* expand 3 eight-bit bytes to four six-bit bytes */
X
X    } else {
X	for (rest = shift = i = 0; i < len; shift = (shift+STEP)%OUT,i++) {
X
X	    c = *buf++ & 0377;				/* No sign extension */
X	    *packptr++ = tosix(rest|(c << shift));	/* Assemble byte */
X	    rest = (c >> (OUT-shift));			/* Save unused bits */
X
X	    if (shift == (OUT-STEP)) {			/* At byte boundary? */
X		*packptr++ = tosix(rest);		/* Make 'fourth' byte */
X		rest = 0;				/* No unused bits now */
X		if (packptr-packbuf > PACKSIZ-4) {	/* Check packet size */
X		    kwproto(fd,packbuf,packptr-packbuf);
X		    packptr = packbuf;
X		}
X	    }
X	}
X	if (shift) {					/* Any bits left? */
X	    *packptr++ = tosix(rest);			/* Put them there */
X	}
X	if (packptr > packbuf) {			/* Flush buffer */
X	    kwproto(fd,packbuf,packptr-packbuf);	/* Ship it off */
X	    packptr = packbuf;
X	}
X	return i;
X    }
X}
X
Xkread(fd,buf,len)
Xint fd;
Xchar *buf;
Xint len;
X{
X    static char packbuf[MAXPACKSIZ] = "";
X    static char *packptr = packbuf;
X    static int  packsiz = 0;
X    register int i,c;
X    static int shift,rest;
X
X    /* set error trap */
X
X    if (setjmp(Failbuf))
X	return FAIL;
X
X    /* read packet if buffer is empty */
X
X    if (packsiz <= 0) {
X	krproto(fd,packptr = packbuf,&packsiz);
X	rest = shift = 0;
X    }
X
X    /* unpack (remainder of) buffer; return 0 if empty packet received */
X
X    for (i = 0; (i < len) && packsiz--; shift = (shift+STEP)%IN) 
X    {
X	c = unsix(*packptr++);
X	if (shift)
X	    buf[i++] = (rest | (c << (IN-shift)));
X	rest = (c >> shift);
X    }
X    return i;
X}
X
Xkclose(fd)
Xint fd;
X{
X    /* not here - pass job to the lower layer that understands packet types */
X
X    kclsproto(fd);
X    return 0;
X}
X
X
END_OF_kpres.c
if test 4951 -ne `wc -c <kpres.c`; then
    echo shar: \"kpres.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f kproto.ms -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"kproto.ms\"
else
echo shar: Extracting \"kproto.ms\" \(2984 characters\)
sed "s/^X//" >kproto.ms <<'END_OF_kproto.ms'
X.TL
Xuucp k protocol description
X.AU
XW.Z. Venema
XEindhoven University of Technology
X.AE
X.NH
XIntroduction
X.LP
XThe k protocol has been developed for the Sytek Localnet local area
Xnetwork at the Eindhoven University of Technology (TUE).
XMain features of this network are:
X.IP     1
XNetwork partners may talk at different baudrates. This implies that the network
Xdoes some buffering. This may cause timing
Xproblems (e.g. a system sending at 9600 baud to a system reading at 1200 baud).
X.IP     2
XThe network needs a flow control mechanism. Usually this is
Xbased on the XON/XOFF protocol. Other control character sequences are used
Xfor commands to the network.
X.IP     3
XSome network stations are connected to telephone modems.
X.LP
XFor these reasons, the k protocol must (i) cope with on XON/XOFF flow
Xcontrol, (ii) be suitable for 7-bit data paths, (iii) avoid
Xcontrol characters and (iv) provide reliable operation
Xover telephone lines as well as over the local area network.
X.NH
XPackets
X.LP
XData are sent as checksummed 256-byte packets, terminated by an
XASCII CR. Except for the packet header (^P), the k protocol only uses
XASCII codes 040 through 0137. Three data bytes are expanded to four
Xbytes upon transmission. Theoretically, this reduces throughput by 25 percent.
XAt 1200 baud, actual performances are:
X.DS
Xuucp, g protocol	110 cps
Xuucp, k protocol	74 cps
Xc-kermit		67 cps
X.DE
XNote that the values for c-kermit are for text files, with repeat-count
Xcompression enabled.
X.PP
XThe packet types are a subset of those used in the kermit programs:
X.DS
XD packets contain data.
XY packets are sent when a correct data packet was received.
XN packets are sent when incorrect data was received.
XA packets are sent to shut down the k protocol.
X.DE
XA packet always begins with a header:
X.DS
XSOH     packet header, ASCII control-P
Xlen     (size of data, low 6 bits) + 32
Xlen     (size of data, high 6 bits) + 32
Xnum     (packet number mod 64) + 32
Xtype    packet type
Xcheck   one-byte type-1 kermit checksum
X.DE
X.LP
XThe header is followed by checksummed data if len > 0:
X.DS
Xdata    len data bytes
Xcheck1  (upper 2 bits of type-3 kermit 16-bit checksum) + 32
Xcheck2  (middle 6 bits of type-3 kermit 16-bit checksum) + 32
Xcheck3  (lower 6 bits of type-3 kermit 16-bit checksum) + 32
X.DE
X.LP
XEvery packet is followed by an ASCII carriage return, which is
Xignored upon reception of a packet. It prevents timeout errors
Xwhen one byte gets lost (the most common case).
X.NH
XHandshake
X.LP
XHandshake is on a per-packet basis; a transmitter will not send
Xanother data packet before it knows that the receiver got the data
Xin good condition. There are various ways to obtain that knowledge:
Xthe receiver may send an ACK message (usual case), or a NAK for
Xthe next data packet, or a data packet with the next sequence number.
X.PP
XThe protocol is aborted when an unexpected
Xpacket type or when a packet out of sequence is received.
XSince 'A' packets are never expected, they always cause a protocol
Xfault.
END_OF_kproto.ms
if test 2984 -ne `wc -c <kproto.ms`; then
    echo shar: \"kproto.ms\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f ktrans.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"ktrans.c\"
else
echo shar: Extracting \"ktrans.c\" \(4983 characters\)
sed "s/^X//" >ktrans.c <<'END_OF_ktrans.c'
X/*++
X/* NAME
X/*	ktrans 3
X/* SUMMARY
X/*	k-protocol strategy routines
X/* PACKAGE
X/*	uucp across the TUEnet
X/* SYNOPSIS
X/*	#include "kp.h"
X/*
X/*	krproto(fd,data,size) 
X/*	int fd, *size;
X/*	char data[MAXPACKSIZ];
X/*
X/*	kwproto(fd,data,size) 
X/*	int fd, size;
X/*	char data[MAXPACKSIZ];
X/*
X/*	kclsproto(fd)
X/*	int fd;
X/* DESCRIPTION
X/*	The functions in this file take care of handshake and error
X/*	detection/recovery. The read/write functions return through an
X/*	external function kfail() in case of fatal errors, or protocol 
X/*	termination by the network partner.
X/*
X/*	The following packet types are used:
X/*
X/* .nf
X/* .in +5
X/*	D packets contain data.
X/*	Y packets are sent when a correct data packet was received.
X/*	N packets are sent when incorrect data was received.
X/*	A packets are sent to shut down the k protocol.
X/* .fi
X/*
X/*	Krproto() sends the data and either returns normally, or through 
X/*	kfail().
X/*
X/*	Kwproto() returns the received data or returns through kfail().
X/*
X/*	Kclsproto() sends the protocol termination sequence to the other 
X/*	side, either to signal the end of transfers, or to confirm
X/*	reception of an end-of-protocol sequence.
X/*
X/*	The strategy for sending data is as follows:
X/*
X/*	Send packet.
X/*	If (ACK for last packet) or (NAK for next packet) received, terminate.
X/*	If (NAK for last packet) or no response received, retransmit.
X/*	If data received with previous packet nr, ignore and wait for NAK.
X/*	If data received with next packet nr, NAK that data and terminate.
X/*	Otherwise (bad packet number, unexpected packet type) abort.
X/*
X/*	The strategy for receiving data is complementary:
X/*
X/*	Wait for packet
X/*	If expected packet received, ACK it and terminate.
X/*	If previous data packet received, ACK it and wait for next packet.
X/*	If bad packet received, send NAK for expected packet.
X/*	If nothing received, wait for another packet.
X/*	Otherwise (bad packet number, unexpected packet type) abort.
X/* FUNCTIONS AND MACROS
X/*	kspack, krpack, kfail
X/* AUTHOR(S)
X/*	Wietse Venema
X/*	Eindhoven University of Technology
X/*	Department of Mathematics and Computer Science
X/*	Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
X/* CREATION DATE
X/*	Mon Feb  3 13:12:08 MET 1986
X/* LAST MODIFICATION
X/*	Mon Apr  4 23:43:42 MET 1988
X/* VERSION/RELEASE
X/*	1.4
X/*--*/
X
X#include "kp.h"
X
Xstatic char recpkt[MAXPACKSIZ];			/* receive packet buffer */
Xstatic int  n = 0;				/* packet number */
X
Xkwproto( fd, packet, size)
Xint fd;
Xchar *packet;
Xint size;
X{
X    int num, numtry;                        	/* Packet number, tries */
X    int len;
X
X    kspack(fd, 'D',n,size,packet);      	/* Send a D packet */
X
X    for (numtry = 0; numtry < MAXTRY; numtry++) {
X	switch(krpack(fd,&num,&len,recpkt)) 	/* What was the reply? */
X	{
X	case 'D':			    	/* DATA */
X	    if ((num+1)%64 == n) {		/* Previous packet ? */
X		numtry = 0;			/* Reset counter */
X		break;				/* Don't ack it; read again */
X	    } else if (num != (n+1)%64)    	/* Fatal error, unless it */
X		kfail();		    	/* carries next packet number */
X	    kspack(fd,'N',num,0,NULLP);   	/* Can't use data now */
X
X	case 'N':                       	/* NAK */
X	    if (n == num) {			/* Send another one, */
X		kspack(fd, 'D',n,size,packet);
X		break;
X	    }
X	    num = (--num<0 ? 63:num); 	/* unless NAK for next packet */
X
X	case 'Y':                       	/* ACK */
X	    if (n != num) kfail();      	/* If wrong ACK, fail */
X	    n = (n+1)%64;               	/* Bump packet count */
X	    return;
X
X	case TIME:				/* No response */
X	case FAIL:				/* Bad packet */
X	    kspack(fd, 'D',n,size,packet);
X	    break;  		    	/* Send data packet again */
X
X	default: 
X	    kfail();               	    	/* Something else, abort */
X	}
X    }
X    kfail();				    	/* Too may retries, abort */
X}
X
Xkrproto( fd, packet, size)
Xint fd;
Xchar *packet;
Xint *size;
X{
X    int num, numtry;                        	/* Packet number, tries */
X
X    for (numtry = 0; numtry < MAXTRY; numtry++) 
X    {
X	switch (krpack(fd,&num,size,packet))	/* Get packet */
X	{
X	case 'D':
X	    if (num == n) {			/* Right packet? */
X		kspack(fd,'Y',n,0,NULLP);	/* Acknowledge the packet */
X		n = (n+1)%64;			/* Bump packet number, mod 64 */
X		return;
X	    } else if (num == ((n==0) ? 63:n-1)) { /* Previous packet? */
X		kspack(fd,'Y',num,0,NULLP);	/* Re-ack previous packet */
X		numtry = 0;	    	    	/* Reset counter */
X		break;				/* Read another packet */
X	    } else
X		kfail();			/* Sorry, wrong number */
X
X	case TIME:				/* No packet */
X	    break;				/* Don't NAK */
X
X	case FAIL:				/* Bad packet */
X	    kspack(fd,'N',n,0,NULLP);		/* Return a NAK */
X	    break;				/* Read another packet */
X
X	default:
X	    kfail();				/* Something else, abort */
X	}
X    }
X    kfail();				    	/* Too may retries, abort */
X}
X
Xkclsproto( fd)
Xint fd;
X{
X    kspack( fd, 'A', 0, 0, NULLP);		/* Send an 'A' packet */
X    kspack( fd, 'A', 0, 0, NULLP);		/* and another two since */
X    kspack( fd, 'A', 0, 0, NULLP);		/* we won't get ACKs */
X    return 0;
X}
END_OF_ktrans.c
if test 4983 -ne `wc -c <ktrans.c`; then
    echo shar: \"ktrans.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
-- 
					Wietse Venema

wswietse@lso.win.tue.nl	| Eindhoven University of Technology 
wswietse@heitue5.bitnet	| 5600 MB Eindhoven, The Netherlands

rsn@mtuxo.att.com (XMRH2-S.NAGARAJ) (09/15/89)

I stumbled on to this news group.  This request has
probably been made several times before....sorry to 
make it here again.

I am looking for information on the g-protocols used in UUCP.
Request netters with e-files to please mail copies to me.

Thanx

raj nagaraj