[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference hydra::amiga_v1

Title:AMIGA NOTES
Notice:Join us in the *NEW* conference - HYDRA::AMIGA_V2
Moderator:HYDRA::MOORE
Created:Sat Apr 26 1986
Last Modified:Wed Feb 05 1992
Last Successful Update:Fri Jun 06 1997
Number of topics:5378
Total number of notes:38326

1048.0. "FS-II multi player mode" by COOKIE::WECKER (A wholly owned subsidiary of DEC) Sun Jan 10 1988 15:27

This note (and its replies) are for FS-II (flight simulator) comments on using
MULTI-PLAYER mode. I will attach all of the info that I have so far to
following replies.

T.RTitleUserPersonal
Name
DateLines
1048.1Current state of explorationsCOOKIE::WECKERA wholly owned subsidiary of DECSun Jan 10 1988 15:3325
Things are not as bleak as I thought.

1)	The stupid program seems to change speeds back from 2400 baud to
	1200 baud when specific items (like ``send aircraft'') happen.

2)	This means that (for all practical purposes) over the phone ONLY
	1200 baud can be used.

3)	This also means that all those funny protocol items (like "break") I
	thought I was getting were really 1200 baud data received at 2400!!

4)	The protocol is simple and straight forward. (See reply on protocol)

5)	It also means that network communication is possible (See reply on
	DECnet operation).

6)	You do NOT need to use Hayes compatible modems (even though that is
	what SubLogic states). Make a connection using something like
	VT100, force DTR, switch over to FS2 and turn it on MULTI-PLAYER-
	ONLINE. That's it. Works fine at 1200 baud modem to modem (using
	a scholar and a multi-tech).

flying along,
dave

1048.2communications protocolCOOKIE::WECKERA wholly owned subsidiary of DECSun Jan 10 1988 15:41242
The protocol is made up of 3 packet types:

	001 Coordinate information
	002 Messages
	003 Airplane information

The packets appear to be fixed length (not yet convinced of "airplane"
packets) and all end with a checksum character (sum of all data bytes MOD 256)

Enclosed here are 2 items:

	1) A dump of a flight script (under 1/20th of its original size)
	2) The program READLOG.C which will read binary flight scripts and
	   dump the human readble version shown in this note.

The program is NOT 100% correct (EAST coordinates need work) but it at least
will show how the packets are sent. All numbers are scaled integers. Some are
32 bit and some are 16 bit.

-----------------------------------------------------------------------------
OUTPUT of READLOC.C:
-----------------------------------------------------------------------------
t    NORTH     ALTITUDE    EAST       PITCH      ROLL      HEADING   CHKSUM
       X          Y         Z        down/up   left/right  compass 
-  ---------- ---------- ---------- ---------- ---------- ---------- ------
C:  17362.324      6.812   4702.208      0.000      0.000    277.071 029
C:  17362.323      6.812   4702.194      0.000      0.000    277.071 0ce
C:  17362.323      6.812   4702.194      0.000      0.000    277.071 0ce
M: STARTING TO ROTATE FROM 277 DEGREES               (chksum = 0)
C:  17362.323      6.812   4702.194      0.000      0.000    277.071 0ce
C:  17362.323      6.812   4702.194      0.000      0.000    278.945 025
C:  17362.323      6.812   4702.194      0.000      0.000    280.819 07b
C:  17362.323      6.812   4702.194      0.000      0.000    282.692 0d1
C:  17362.323      6.812   4702.194      0.000      0.000    284.566 028
C:  17362.323      6.812   4702.194      0.000      0.000    286.440 07e
C:  17362.323      6.812   4702.194      0.000      0.000    288.313 0d4
C:  17362.323      6.812   4702.194      0.000      0.000    290.187 02b
C:  17362.323      6.812   4702.194      0.000      0.000    292.060 081
C:  17362.323      6.812   4702.194      0.000      0.000    293.934 0d7
C:  17362.323      6.812   4702.194      0.000      0.000    295.808 02e
C:  17362.323      6.812   4702.194      0.000      0.000    297.681 084
C:  17362.323      6.812   4702.194      0.000      0.000    299.555 0da
C:  17362.323      6.812   4702.194      0.000      0.000    301.429 031
C:  17362.323      6.812   4702.194      0.000      0.000    303.302 087
C:  17362.323      6.812   4702.194      0.000      0.000    305.923 066
C:  17362.323      6.812   4702.194      0.000      0.000    308.544 045
C:  17362.323      6.812   4702.194      0.000      0.000    311.165 024
C:  17362.323      6.812   4702.194      0.000      0.000    313.786 002
C:  17362.323      6.812   4702.194      0.000      0.000    316.407 0e1
C:  17362.323      6.812   4702.194      0.000      0.000    319.027 0c0
C:  17362.323      6.812   4702.194      0.000      0.000    321.648 09f
C:  17362.323      6.812   4702.194      0.000      0.000    324.269 07e
C:  17362.323      6.812   4702.194      0.000      0.000    326.802 05d
C:  17362.323      6.812   4702.194      0.000      0.000    329.423 03c
C:  17362.323      6.812   4702.194      0.000      0.000    332.044 01b
C:  17362.323      6.812   4702.194      0.000      0.000    334.665 0f9
C:  17362.323      6.812   4702.194      0.000      0.000    337.286 0d8
C:  17362.323      6.812   4702.194      0.000      0.000    339.907 0b7
C:  17362.323      6.812   4702.194      0.000      0.000    342.527 096
C:  17362.323      6.812   4702.194      0.000      0.000    345.148 075
C:  17362.323      6.812   4702.194      0.000      0.000    347.769 054
C:  17362.323      6.812   4702.194      0.000      0.000    350.390 033
C:  17362.323      6.812   4702.194      0.000      0.000    353.011 011
C:  17362.323      6.812   4702.194      0.000      0.000    355.632 0f0
C:  17362.323      6.812   4702.194      0.000      0.000    358.253 0cf
C:  17362.323      6.812   4702.194      0.000      0.000      1.956 074
M: PUTTING GEAR UP                                   (chksum = 0)
C:  17362.323      6.812   4702.194      0.000      0.000      1.956 074
A: <aircraft info being received>
C:  17362.323      6.812   4702.194      0.000      0.000      1.956 074
C:  17362.323      6.812   4702.194      0.000      0.000      0.456 062
C:  17362.323      6.812   4702.194      0.000      0.000    358.956 050
M: PUTTING GEAR DOWN                                 (chksum = 0)
C:  17362.323      6.812   4702.194      0.000      0.000    357.456 03e
A: <aircraft info being received>
C:  17362.323      6.812   4702.194      0.000      0.000    355.956 02c
M: GOING UP TO 1000 FEET                             (chksum = 0)
C:  17360.817      6.812   4722.792      0.000      0.000     92.962 021
C:  17360.817     14.111   4722.792      0.000      0.000     92.962 07b
C:  17360.817     23.842   4722.792      0.000      0.000     92.962 09e
C:  17360.817     67.633   4722.792      0.000      0.000     92.962 0bc
C:  17360.817    126.022   4722.792      0.000      0.000     92.962 08f
C:  17360.817    271.993   4722.792      0.000      0.000     92.962 09e
C:  17360.817    478.786   4722.792      0.000      0.000     92.962 048
C:  17360.817    722.071   4722.792      0.000      0.000     92.962 0b6
C:  17360.817    916.699   4722.792      0.000      0.000     92.962 076
C:  17360.817   1159.984   4722.792      0.000      0.000     92.962 0e4
C:  17360.817    962.923   4722.792      0.000      0.000     92.962 05d
C:  17360.817    953.192   4722.792      0.000      0.000     92.962 03a
C:  17360.817    950.759   4722.792      0.000      0.000     92.962 071
M: AT 1000 FEET                                      (chksum = 0)
C:  17360.817    950.759   4722.792      0.000      0.000     92.962 071
M: LEFT BANK                                         (chksum = 0)
C:  17360.817    950.759   4722.792      0.000      0.000     92.962 071
C:  17360.817    950.759   4722.792      0.000      0.352     92.962 0b1
C:  17360.817    950.759   4722.792      0.000      0.703     92.962 0f1
C:  17360.817    950.759   4722.792      0.000      1.055     92.962 031
C:  17360.817    950.759   4722.792      0.000      1.758     92.962 0b2
C:  17360.817    950.759   4722.792      0.000      2.813     92.962 073
C:  17360.817    950.759   4722.792      0.000      4.220     92.962 074
C:  17360.817    950.759   4722.792      0.000      5.978     92.962 0b5
C:  17360.817    950.759   4722.792      0.000      8.440     92.962 077
C:  17360.817    950.759   4722.792      0.000     11.253     92.962 079
C:  17360.817    950.759   4722.792      0.000     14.418     92.962 0bb
C:  17360.817    950.759   4722.792      0.000     17.582     92.962 0fd
C:  17360.817    950.759   4722.792      0.000     93.187     91.462 0e1
C:  17360.817    950.759   4722.792      0.000     93.538     91.462 021
C:  17360.817    950.759   4722.792      0.000     93.890     91.462 061
M: ABOUT 90 DEGRESS...                            (chksum = 0)
C:  17360.817    950.759   4722.792      0.000     93.890     91.462 061
C:  17360.817    950.759   4722.792      0.000     93.538     91.462 021
C:  17360.817    950.759   4722.792      0.000     92.835     91.462 0a1
C:  17360.817    950.759   4722.792      0.000     91.780     91.462 0e0
C:  17360.817    950.759   4722.792      0.000     90.022     91.462 09f
M: NOSE UP                                           (chksum = 0)
C:  17360.817    950.759   4722.792      0.000      0.352     91.462 09f
C:  17360.817    950.759   4722.792     -0.352      0.352     91.462 05e
C:  17360.817    950.759   4722.792     -0.703      0.352     91.462 01e
C:  17360.817    950.759   4722.792     -1.407      0.352     91.462 09e
C:  17360.817    950.759   4722.792     -2.110      0.352     91.462 01d
C:  17360.817    950.759   4722.792     -3.165      0.352     91.462 05c
C:  17360.817    950.759   4722.792     -4.571      0.352     91.462 05b
C:  17360.817    950.759   4722.792     -5.978      0.352     91.462 05a
C:  17360.817    950.759   4722.792     -7.385      0.352     91.462 059
C:  17360.817    950.759   4722.792     -8.791      0.352     91.462 058
C:  17360.817    950.759   4722.792    -10.198      0.352     91.462 057
C:  17360.817    950.759   4722.792    -11.604      0.352     91.462 056
C:  17360.817    950.759   4722.792    -13.011      0.352     91.462 055
C:  17360.817    950.759   4722.792    -14.418      0.352     91.462 054
C:  17360.817    950.759   4722.792    -15.824      0.352     91.462 053
C:  17360.817    950.759   4722.792    -17.231      0.352     91.462 052
C:  17360.817    950.759   4722.792    -18.637      0.352     91.462 051
C:  17360.817    950.759   4722.792    -20.044      0.352     91.462 050
C:  17360.817    950.759   4722.792    -21.451      0.352     91.462 04f
C:  17360.817    950.759   4722.792    -22.857      0.352     91.462 04e
C:  17360.817    950.759   4722.792    -81.934      0.352     91.462 024
C:  17360.817    950.759   4722.792    -82.989      0.352     91.462 064
C:  17360.817    950.759   4722.792    -84.044      0.352     91.462 0a3
C:  17360.817    950.759   4722.792    -85.099      0.352     91.462 0e2
C:  17360.817    950.759   4722.792    -86.154      0.352     91.462 021
C:  17360.817    950.759   4722.792    -87.209      0.352     91.462 061
C:  17360.817    950.759   4722.792    -88.264      0.352     91.462 0a0
C:  17360.817    950.759   4722.792    -89.319      0.352     91.462 0df
C:  17337.422  28466.427   5052.009      0.000      0.352     79.934 033
M: ALL DONE... BYE BYE!                              (chksum = 0)
C:  17337.422  28466.427   5052.009      0.000      0.352     79.934 033

-----------------------------------------------------------------------------
READLOG.C:
-----------------------------------------------------------------------------
#include <stdio.h>

main() {
    char	str[50];
    int		c,data[20];
    int		i,j,state = 0,sum;
    double	d;

    printf("t    NORTH     ALTITUDE    EAST       PITCH      ROLL      HEADING\n");
    printf("       X          Y         Z        down/up   left/right  compass\n");
    printf("-  ---------- ---------- ---------- ---------- ---------- ----------\n");
    while ((c=getchar()) != EOF) {
	switch (state) {
	    case 0: /* waiting for packet to start */
	    if (c == 229) state = 1;
	    break;

	    case 1: /* getting packet type */
	    if (c < 10)		    state = c+1;
	    else		    state = 0;
	    break;

	    case 2: /* coordinate info being sent */
	    data[0] = c;
	    for (i=1; i<19; i++)
		if ((data[i] = getchar()) == EOF) exit(1);
	    printf("C: ");
	    j   = data[3] | (data[2]<<8) | (data[1]<<16) | (data[0]<<24);
	    j >>= 1;
	    j  &= 0x7FFFFFFF;
	    d = ((double)j) / 102446.436;
	    printf("%10.3f ",d);
	    j = data[7] | (data[6]<<8) | (data[5]<<16) | (data[4]<<24);
	    j >>= 1;
	    j  &= 0x7FFFFFFF;
	    d = ((double)j) / 41.104;
	    printf("%10.3f ",d);
	    j = data[11] | (data[10]<<8) | (data[9]<<16) | (data[8]<<24);
	    j >>= 1;
	    j  &= 0x7FFFFFFF;
	    d = ((double)j) / 6817.61;
	    printf("%10.3f ",d);
	    j = data[13] | (data[12]<<8);
	    if (j & 0x8000) j |= 0xFFFF0000;
	    d = ((double)j) / 182.0;
	    printf("%10.3f ",d);
	    j = data[15] | (data[14]<<8);
	    if (j & 0x8000) j |= 0xFFFF0000;
	    d = ((double)j) / 182.0;
	    printf("%10.3f ",d);
	    j  = data[17] | (data[16]<<8);
	    d  = ((double)j) / 182.0;
	    d -= 35.0;
	    if (d < 0.0) d += 360.0;
	    printf("%10.3f ",d);
	    j = data[18];
	    printf("%03x\n",j);
	    state = 0;
	    break;

	    case 3: /* message being sent */
	    sum	    = c & 0xFF;
	    str[0]  = c & 0x7F;
	    for (i=1; i<50; i++) {
		if ((c = getchar()) == EOF) exit(1);
		c &= 0xFF;
		if (i == 49)	sum -= c;
		else		sum += c;
		sum   &= 0xFF;
		str[i] = c & 0x7F;
		}
	    str[49] = '\000';
	    printf("M: %s (chksum = %d)\n",str,sum);
	    state = 0;
	    break;

	    case 4: /* aircraft info being sent */
	    printf("A: <aircraft info being received>\n");
	    state = 0;
	    break;

	    default: /* unkonwn packet type */
	    printf("U: <unknown packet type %d>\n",state-1);
	    state = 0;
	    break;
	    }
	}
    exit(0);
    }
	
-----------------------------------------------------------------------------

1048.3DECnet FS2 programCOOKIE::WECKERA wholly owned subsidiary of DECSun Jan 10 1988 16:00507
We finally got a DECnet program working. It turned into a general purpose
message mover (I just can't stop :-) for network testing... so it may be
useful to people outside of the ``FS-II'' domain.

The program (in its simplest form) allows two people to connect by issuing
the following commands:

Person 1:	% fs2
		SERVER: Waiting for a connection...


Person 2:	% fs2 child			(node name of other user)
		CLIENT: Connecting to server......


Both then get CONNECTED messages. At this point you are up and running. The
terminals have been switched into raw binary mode and FS-II can do it's bit.

When you wish to terminate a link, a string of '@@@@@' (5 at signs) on either
side of the link will break off connections for both parties.

The program has ALOT of switches. Here is a summary:

	    Usage:   fs2 [options] [client-node]
	    Default: fs2 -p -g (if no switches but -a or -e)

	       -a     = ASCII mode (instead of binary default)
	       -e     = ECHO  mode (instead of noecho default)
	       -l     = local loopback
	       -r     = remote loop back
	       -p     = local input        => remote output
	       -o fil = local input        => file
	       -m fil = local,remote input => file
	       -g     = local output      <=  remote input
	       -t fil = file              <=  remote input
	       -i fil = file replaces local input
	       -s fil = file replaces remote input

The options possible can be shown graphically:

      I  ----------        ------> O    
                   \      /
                    \    /
         ------------>  ---------- P     ----->  --------->
                      |  \                     ^
        T             |   \                    |         
        E             |    \                   |         S
        R             |     \                  |         O
        M                    \                           C
        I             L       ---> M <----     R         K
        N                                 \              E
        A             |                    \   |         T
        L             |                     \  |
                      V                      \ |
         <------------  <--------- G     -----   <---------
                                             /    \
                                            /      \     
                                   T <------        ------- S
 


For example, to just test the program you could use:


	% fs2 -a -l

which would create an ASCII local loopback (echo typing).

	% fs2 -r

would create a server that would echo anything comming over the DECnet link.

	% fs2 -o foo.log

would create a log of a flight.

	% fs2 -o foo2.log -s foo.log -g

would create a log (foo2) of this flight and at the same time play back
the previous log (foo) to my simulator.


There are LOTS of other possibilities. Note the following:

	1)	When pick any option (other than -a or -e) all defaults
		will be turned off (-g and -p) so you must turn them back
		on if you want them (like the last example).

	2)	The program is smart enough to recognize FS-II packets and
		tries to write DECnet packets that are groups of FS-II
		packets (if possible).

	3)	If you input from a file (-i or -s) at EOF both ends of
		the link will terminate.

	4)	THE BIGGEE: This ONLY runs on VMS. Brad Morgan said he'd
		look into doing a VMS version (schedule permitting) but
		anyone who wants to take a crack at it is welcome to try.


	5)	Also note that the program uses SEQUENTAL STREAM protocol
		and will probably have to change to SEQUENTIAL PACKET for
		VMS.

Enjoy!
dave



/***************************************************************************
 *
 * FS2 - flight simulator host program (general DECnet interchange program)
 *
 *  V1.0    880102	DBW - First hack
 *  V2.0    880109	DBW - First REAL version
 *
 * Switches and descriptors (descs[10]):
 *
 *    -a = ASCII mode (as opposed to binary (default))
 *    -e = ECHO  mode (as opposed to no echo (default))
 *
 *     I  ----------        ------> O (2)
 *           (8)    \      /
 *                   \    /
 *        ------------>  ---------- P (0) ----->  --------->
 *                     |  \                     ^
 *       T             |   \                    |         
 *       E             |    \                   |         S
 *       R             |     \                  |         O
 *       M                    \                           C
 *       I             L (1)   ---> M <----     R (5)     K
 *       N                        (3,7)    \              E
 *       A             |                    \   |         T
 *       L             |                     \  |
 *                     V                      \ |
 *        <------------  <--------- G (4) -----   <---------
 *                                            /    \
 *                                           /      \  (9)
 *                              (6) T <------        ------- S
 *
 **************************************************************************/


#include<stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/file.h>
#include <netdnet/dn.h>
#include <netdnet/dnetdb.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <sgtty.h>

#define BUFFER_SIZE 1024
#define HIGHWATER   (BUFFER_SIZE>>2)

#define no_eintr(x) while ((x) == -1 && errno == EINTR)

extern int  errno;
extern char *optarg;
extern int  optind;

int	    s = -1, ns = -1, acclen, dosock = 0, bin = 0, block = 0;
char	    buf1[BUFFER_SIZE],buf2[BUFFER_SIZE];
struct	    sockaddr_dn sockaddr, accsockaddr;
struct	    sgttyb ostate,nstate;
int	    descs[10];

int	     lflg = 0,
	     rflg = 0,
	     pflg = 0,
	     gflg = 0,
	     aflg = 0,
	     eflg = 0;
char	    *oflg = NULL,
	    *sflg = NULL,
	    *iflg = NULL,
	    *tflg = NULL,
	    *mflg = NULL;

ERROR(name)
char	*name;
    {
    if (block) {
	if (descs[8] != -1)	
	    fcntl(descs[8],F_SETFL,fcntl(descs[8],F_GETFL,0) & ~FNDELAY);
	if (descs[9] != -1)	
	    fcntl(descs[9],F_SETFL,fcntl(descs[9],F_GETFL,0) & ~FNDELAY);
	}
    if (bin) stty(0, &ostate);
    if (descs[2] != -1)	close(descs[2]);
    if (descs[3] != -1) close(descs[3]);
    if (descs[6] != -1) close(descs[6]);
    if (descs[8] != -1) close(descs[8]);
    if (sflg)		close(descs[9]);
    if (s  != -1)	close(s);
    if (ns != -1)	close(ns);
    if (name) {
	perror(name);
	/* freopen("fs2.debug","w",stderr);
	 *  perror(name);
	 *  fclose(stderr);
	 */
	exit(1);
	}
    exit(0);
    }

msg(str)
char	*str;
    {
    if (lflg || gflg) {
	write(1,str,strlen(str));
	if (!aflg) write(1,"\r",1);
	}
    }

main(argc,argv)
char **argv;
    {
    int	i,opt,dodefault = 1;


    for (i=0;i<10;i++) descs[i] = -1;

    while ((opt=getopt(argc,argv,"aepglri:o:s:t:m:")) != EOF) {
	if (opt != 'a' && opt != 'e') dodefault = 0;
	switch (opt) {
	    case 'a':	aflg++;		break;
	    case 'e':	eflg++;		break;
	    case 'p':	pflg++;		break;
	    case 'g':	gflg++;		break;
	    case 'l':	lflg++;		break;
	    case 'r':	rflg++;		break;
	    case 'i':	iflg = optarg;	break;
	    case 'o':	oflg = optarg;	break;
	    case 's':	sflg = optarg;	break;
	    case 't':	tflg = optarg;	break;
	    case 'm':	mflg = optarg;	break;

	    default:
	    printf("Usage:   fs2 [options] [client-node]\n");
	    printf("Default: fs2 -p -g (if no switches but -a or -e)\n\n");
	    printf("   -a     = ASCII mode (instead of binary default)\n");
	    printf("   -e     = ECHO  mode (instead of noecho default)\n");
	    printf("   -l     = local loopback\n");
	    printf("   -r     = remote loop back\n");
	    printf("   -p     = local input        => remote output\n");
	    printf("   -o fil = local input        => file\n");
	    printf("   -m fil = local,remote input => file\n");
	    printf("   -g     = local output      <=  remote input\n");
	    printf("   -t fil = file              <=  remote input\n");
	    printf("   -i fil = file replaces local input\n");
	    printf("   -s fil = file replaces remote input\n\n");
	    ERROR("BAD COMMAND LINE");
	    }
	}

    if (dodefault) {
	pflg++;
	gflg++;
	}

    if (iflg)
	if ((descs[8] = open(iflg,O_RDONLY,0644)) < 0) ERROR("bad -i file");
    if (sflg)
	if ((descs[9] = open(sflg,O_RDONLY,0644)) < 0) ERROR("bad -s file");
    if (oflg)
	if ((descs[2] = open(oflg,O_WRONLY|O_CREAT|O_TRUNC,0644)) < 0)
						       ERROR("bad -o file");
    if (tflg)
	if ((descs[6] = open(tflg,O_WRONLY|O_CREAT|O_TRUNC,0644)) < 0)
						       ERROR("bad -t file");
    if (mflg)
	if ((descs[3] = open(mflg,O_WRONLY|O_CREAT|O_TRUNC,0644)) < 0)
						       ERROR("bad -m file");
    descs[7] = descs[3];
    if (lflg)	descs[1] = 1;
    if (gflg)	descs[4] = 1;
    if (!iflg)	descs[8] = 0;

    if (pflg || rflg)			    dosock = 1;
    if (!sflg && (gflg || mflg || tflg))    dosock = 1;

    gtty(0, &ostate);
    gtty(0, &nstate);

    if (!aflg) {
	nstate.sg_flags |= RAW;
	nstate.sg_flags &= ~CRMOD;
	}
    if (!eflg)
	nstate.sg_flags &= ~ECHO;

    if (pflg || lflg || gflg || (oflg && !iflg)) {
	stty(0, &nstate);
	bin = 1;
	}
    else if (!iflg) descs[8] = -1;

    if (dosock) {
	if ((s = socket(AF_DECnet,SOCK_STREAM,0)) <= 0) ERROR(argv[0]);
	sockaddr.sdn_family = AF_DECnet;
	sockaddr.sdn_objnum = 173;

	if (optind < argc) client(argv[optind]);
	
	msg("SERVER: Waiting for client to connect\n");
	if (bind(s,&sockaddr,sizeof(struct sockaddr_dn)) < 0) ERROR(argv[0]);
	if (listen(s,1) < 0) ERROR(argv[0]);
	no_eintr(ns=accept(s,&accsockaddr,&acclen));
	msg("SERVER: Connected!\n");
	if (pflg)   descs[0] = ns;
	if (rflg)   descs[5] = ns;
	if (!sflg)  descs[9] = ns;
	}

    
    transfer();

    if (dosock) msg("SERVER: Exiting...\n");

    ERROR(NULL);
    }

client(nodename)
char	*nodename;
    {
    struct  nodeent *nodep, *getnodebyname();


    msg("CLIENT: Waiting for server to respond\n");
    if ((nodep = getnodebyname(nodename)) == NULL) ERROR("fs2: Node unknown");
    bcopy(nodep->n_addr,sockaddr.sdn_nodeaddr,nodep->n_length);
    sockaddr.sdn_nodeaddrl = nodep->n_length;
    if (connect(s,&sockaddr,sizeof(struct sockaddr_dn)) < 0) ERROR("fs2");
    msg("CLIENT: Connected!\n");
    if (pflg)   descs[0] = s;
    if (rflg)   descs[5] = s;
    if (!sflg)  descs[9] = s;

    transfer();

    msg("CLIENT: Exiting...\n");

    ERROR(NULL);
    }

transfer() {
    int	    i,j,k,a,flag,base1,base2,len1,len2,eof1,eof2;
    void    mysleep();

    eof1   = eof2  = 0;    
    base1  = base2 = 0;

    if (descs[8] != -1)	
	fcntl(descs[8],F_SETFL,fcntl(descs[8],F_GETFL,0)|FNDELAY);
    if (descs[9] != -1)	
	fcntl(descs[9],F_SETFL,fcntl(descs[9],F_GETFL,0)|FNDELAY);
    block = 1;

    while (1) {
	flag  = 0;
	if (descs[8] == -1) flag |= 1;
	if (descs[9] == -1) flag |= 2;

	while (flag != 3 && base1 < HIGHWATER && base2 < HIGHWATER &&
		eof1 < 5 && eof2 < 5) {
	    if (descs[8] != -1) {
		len1 = read(descs[8],&buf1[base1],BUFFER_SIZE-base1);
		if (len1 == -1) {
		    if (errno != EWOULDBLOCK) ERROR("fs2");
		    flag |= 1;
		    }
		if (len1 == 0) eof1 = 5;
		for (i=0; i<len1; i++) {
		    if (buf1[base1+i] == '@') {
			if (++eof1 >= 5) break;
			}
		    else eof1 = 0;
		    }
		if (len1 >  0) base1 += len1;
		}
	    if (descs[9] != -1) {
		len2 = read(descs[9],&buf2[base2],BUFFER_SIZE-base2);
		if (len2 == -1) {
		    if (errno != EWOULDBLOCK) ERROR("fs2");
		    flag |= 2;
		    }
		if (len2 == 0) eof2 = 5;
		for (i=0; i<len2; i++) {
		    if (buf2[base2+i] == '@') {
			if (++eof2 >= 5) break;
			}
		    else eof2 = 0;
		    }
		if (len2 >  0) base2 += len2;
		}
	    }
	
	if (base1) {
	    for (j=base1-2; j>=0; j--)
		if (buf1[j] == 229 && buf1[j+1] < 10) break;
	    if (j<=0 || eof1 >= 5) j = base1;
	    for (i=0; i<4; i++)
		if (descs[i] != -1) {
		    for(k=j; k; k -= a) {
			a = write(descs[i],&buf1[j-k],k);
			if (a == -1) {
			    if (errno != EWOULDBLOCK) ERROR("fs2");
			    mysleep(0,200000);
			    a = 0;
			    }
			}
		    }
	    for (i=0; j<base1; j++,i++)	buf1[i] = buf1[j];
	    base1 = i;
	    }

	if (base2) {
	    for (j=base2-2; j>=0; j--)
		if (buf2[j] == 229 && buf2[j+1] < 10) break;
	    if (j<=0 || eof2 >= 5) j = base2;
	    for (i=4; i<8; i++)
		if (descs[i] != -1) {
		    for(k=j; k; k -= a) {
			a = write(descs[i],&buf2[j-k],k);
			if (a == -1) {
			    if (errno != EWOULDBLOCK) ERROR("fs2");
			    mysleep(0,200000);
			    a = 0;
			    }
			}
		    }
	    for (i=0; j<base2; j++,i++)	buf2[i] = buf2[j];
	    base2 = i;
	    }

	if (eof1 >= 5 || eof2 >= 5) return;

	if (flag == 3) {
	    if (iflg||sflg)			       return;
	    if (dosock &&  pflg && dnet_eof(descs[0])) return;
	    if (dosock &&  rflg && dnet_eof(descs[5])) return;
	    if (dosock && !sflg && dnet_eof(descs[9])) return;
	    mysleep(0,200000);
	    }
	}
    }


#define	mask(s)		(1<<((s)-1))
#define	setvec(vec, a)	vec.sv_handler = a; vec.sv_mask = vec.sv_onstack = 0

static int ringring;

void mysleep(n,n2)
unsigned n,n2;
    {
    int				mysleepx(), omask;
    struct itimerval		itv, oitv;
    register struct itimerval	*itp = &itv;
    struct sigvec		vec, ovec;

    if (n == 0 && n2 == 0) return;
    timerclear(&itp->it_interval);
    timerclear(&itp->it_value);
    if (setitimer(ITIMER_REAL, itp, &oitv) < 0)	return;
    setvec(ovec, SIG_DFL);
    omask = sigblock(0);
    itp->it_value.tv_sec  = n;
    itp->it_value.tv_usec = n2;
    if (timerisset(&oitv.it_value)) {
	if (timercmp(&oitv.it_value, &itp->it_value, >)) {
	    oitv.it_value.tv_sec  -= itp->it_value.tv_sec;
	    oitv.it_value.tv_usec -= itp->it_value.tv_usec;
	    if (oitv.it_value.tv_usec < 0) {
		oitv.it_value.tv_usec += 1000000;
		oitv.it_value.tv_sec--;
		}
	    }
	else {
	    itp->it_value = oitv.it_value;
	    oitv.it_value.tv_sec = 0;
	    oitv.it_value.tv_usec = 10000;
	    }
	}
    setvec(vec, mysleepx);
    (void) sigvec(SIGALRM, &vec, &ovec);
    ringring = 0;
    (void) setitimer(ITIMER_REAL, itp, (struct itimerval *)0);
    while (!ringring) sigpause(omask &~ mask(SIGALRM));
    (void) sigvec(SIGALRM, &ovec, (struct sigvec *)0);
    (void) setitimer(ITIMER_REAL, &oitv, (struct itimerval *)0);
    }

static mysleepx()
    {
    ringring = 1;
    }