
GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 1
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (1)



    1        	/*
    2        	 * @(#)gio.c 1.8 87/09/29	Copyright 1987 Free Software Foundation, Inc.
    3        	 *
    4        	 * Copying and use of this program are controlled by the terms of the
    5        	 * GNU Emacs General Public License.
    6        	 *
    7        	 * Derived from:
    8        	 * i[$]uuslave.c	1.7 08/12/85 14:04:20
    9        	 * which came from the ACGNJ BBS system at +1 201 753 9758.  Original
   10        	 * author unknown.
   11        	 */
   12        	
   13        	#ifndef lint
   14        	char gio_version[] = "@(#)gio.c hoptoad-1.8 87/09/29";
   15        	#endif
   16        	
   17        	#include "includes.h"		/* All the system header files */
 2946        	#include "uucp.h"
 3032        	#include "sysdep.h"
 3136        	
 3137        	extern int errno;
 3138        	
 3139        	/*
 3140        	

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 2
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (2)

             	
 3141        	This program implements the uucp (Unix-to-Unix CoPy) protocol as a
 3142        	slave (the recipient of a phone call from another Unix system) or, now,
 3143        	a master (the originator of a phone call).  This
 3144        	protocol is used to transfer mail, files, and Usenet news from Unix
 3145        	machine to Unix machine.  UUCP comes with Unix (unless you get a
 3146        	sleazeoid version like Xenix, where they charge you extra for it).  You
 3147        	can buy a commercial program for MSDOS, called UULINK, which also
 3148        	implements this protocol.  UULINK costs $300 and you don't get sources,
 3149        	though.
 3150        	
 3151        	The protocol requires a full 8-bit data path with no characters inserted
 3152        	or deleted (e.g. ^S and ^Q are used as DATA characters).  Simple serial
 3153        	ports and modems do this; most complicated networks do not, at least without
 3154        	setting up odd modes and such.  Telenet's PC Pursuit works fine though.
 3155        	
 3156        	The basic flow of the protocol is that the calling machine will send down
 3157        	a line of text saying what it wants to do (send a file, receive a file,
 3158        	or hang up).  (The lines of text are encapsulated into packets; see below.)
 3159        	The called machine responds with a "yes" or "no" answer, and if the answer
 3160        	was yes, it sends or receives the file.  Files are terminated with a
 3161        	packet containing 0 bytes of data.  Then the system that received the file
 3162        	sends a "copy succeeded" or "copy failed" line to the other end, and 
 3163        	they go back to "what do we do now".  A request to hang up should be
 3164        	answered "no" if the called machine has some mail or files it wants to
 3165        	send to the calling machine; the two machines reverse roles and the calling
 3166        	machine goes into "what do we do now".  If a hangup request is answered "yes",
 3167        	the call is terminated.
 3168        	
 3169        	The data flow described above is actually sent in packets containing
 3170        	checksums and acknowledgements.  Each packet can either hold a short
 3171        	control message, e.g. an ack, or a data block.  The data blocks are
 3172        	numbered with a 3-bit counter, and sent with a checksum.  If the sender
 3173        	has not received an acknowledgement for a data block within a certain
 3174        	time, it retransmits the block.  The size of a data block is negotiated
 3175        	at the start of a call.  To send a block with fewer bytes, a "short
 3176        	data" block is sent, which is just as big as a "long data" block, but
 3177        	contains a 1- or 2-byte count of "how many bytes in this block are just
 3178        	padding".  This is a cute trick since it always works (e.g. if you want
 3179        	to send 1023 out of 1024 bytes, you only need one byte for the count;
 3180        	while if you want to send 1 byte out of 1024 then you have enough space
 3181        	for the count to be 2 bytes).
 3182        	
 3183        	The short control messages are used to start the call and negotiate the
 3184        	packet size and the "window size", to acknowledge or reject packets,
 3185        	and to terminate the packet protocol at the end of a call.  The window
 3186        	size is how many packets one side can send before it will stop and wait
 3187        	for an acknowledgement from the other side.  A window size of 1 makes
 3188        	for a half-duplex protocol (which is what uuslave currently
 3189        	implements), but also makes it easy to implement on micros that don't
 3190        	handle serial lines with interrupts.  In window 1, you just keep
 3191        	sending the same packet until the other side acknowledges it.  Unix
 3192        	always uses a window size of 3, which is the max that can be dealt with
 3193        	given the 3-bit packet numbers (for reasons that would take more space
 3194        	than I want to spend here).  This gives much better throughput, but
 3195        	requires full duplex serial port handling and more complicated
 3196        	acknowledgement strategies.

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 3
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (2)

 3197        	
 3198        	At the low level, full 8-bit bytes are sent out and received on an async serial
 3199        	port.  The received data is scanned for a DLE (hex 10) which indicates the
 3200        	start of a packet, and the next 5 bytes are read and checked.  If they
 3201        	pass, this is a good packet and it is acted upon.  (If it's a data
 3202        	packet, we have to read in and check the data part too.)  If the checks
 3203        	fail, all the bytes read so far should be scanned for another DLE.
 3204        	*/
 3205        	

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 4
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (3)

             	
 3206        	/*
 3207        	 * UUCP "g" procotol definitions
 3208        	 */
 3209        	#define	MAGIC	0125252		/* checksum is subtracted from this */
 3210        	
 3211        	/*
 3212        	 * What is sent from one machine to the other is a control byte and
 3213        	 * sometimes a data block following.
 3214        	 * A packet is a just this, with a frame around the control byte and the
 3215        	 * data, if any, after the frame.  The frame is 6 bytes long, and looks like:
 3216        	 *	DLE K C0 C1 C X
 3217        	 * where:
 3218        	 *	DLE is a literal ASCII DLE (Data Link Escape) character
 3219        	 *	K is binary, 9 for a control packet, or the packet size log 2, minus 4
 3220        	 *		e.g. K = 2 means 64 byte packet since  (K+4) is  6 or 64.
 3221        	 *						      2         2
 3222        	 *	C0 and C1 are low, high order checksums for the entire data section, or
 3223        	 *		are low, high order of (MAGIC minus the control byte).
 3224        	 *	C is the control byte for the message.
 3225        	 *	X is the xor of K, C0, C1, and C.
 3226        	 * If a packet does not satisfy all of the above checks, it is invalid.
 3227        	 */
 3228        	#define	DLE	0x10		/* Start of packet indicator */
 3229        	
 3230        	#define	LENBYTE	1		/* Byte offset from DLE to length */
 3231        	#define	CBYTE	4		/* Byte offset from DLE to control */
 3232        	#define	FRAMEBYTE 5		/* Byte offset from DLE to end of frame */
 3233        	
 3234        	#define	KCONTROL 9		/* K value for control packets */
 3235        	
 3236        	/*
 3237        	 * A control byte is split into three bit fields: type, x, and y.
 3238        	 * 	TT XXX YYY
 3239        	 * Here are the types:
 3240        	 */
 3241        	#define	CONTROL	0		/* Control message */
 3242        	#define	ALTCHN	1		/* Alternate channel message, unused in UUCP */
 3243        	#define	LONGDATA	2	/* Long data block -- full size spec'd by K */
 3244        	#define	SHORTDATA	3	/* Short data block -- first byte or two is
 3245        					   count.  Full K-size packet is sent, even
 3246        					   though the useful data is shorter. */
 3247        	
 3248        	char *tt_pr[] = {"CONTROL", "ALTCHN", "LONGDATA", "SHORTDATA"};
 3249        	
 3250        	/* If TT == CONTROL (also K will == KCONTROL) then
 3251        	   the x field is: 			and the Y field means: */
 3252        	#define	CLOSE	1	/* End of communication */
 3253        	#define	RJ	2	/* Reject packet	last good packet # seen */
 3254        	#define	SRJ	3	/* Selective reject	seq # of bad packet, resend
 3255        				   SRJ is not used by UUCP. */
 3256        	#define	RR	4	/* Receiver Ready	last good packet # seen */
 3257        	#define	INITC	5	/* Init phase C		window size to hand sender */
 3258        	#define	INITB	6	/* Init phase B		max data segment size (K val)
 3259        							to hand sender */
 3260        	#define	INITA	7	/* Init phase A		window size to hand sender */
 3261        	

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 5
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (3)

 3262        	char *ctrl_pr[] = {"*ZERO*",
 3263        		"CLOSE", "RJ", "SRJ", "RR", "INITC", "INITB", "INITA"};
 3264        	
 3265        	/*
 3266        	 * If TT == LONGDATA or SHORTDATA then x field is the sequence # of this packet
 3267        	 * and y field is the last good packet # seen.
 3268        	 *
 3269        	 * In both data and RJ/RR packets, the "last good packet # seen" starts off
 3270        	 * as zero.
 3271        	 */
 3272        	
 3273        	
 3274        	#define	MAX_PACKET	4096
 3275        	
 3276        	unsigned char	msgi[MAX_PACKET+SLOP],	/* Incoming packet */
 3277        			msgo[MAX_PACKET+SLOP];	/* Outgoing packet */
 3278        	
 3279        	int	firstslave,			/* First packet of slave's session */
 3280        		msgsize,			/* Size of data part of msg */
 3281        		tt, xxx, yyy,			/* Fields from control byte */
 3282        		rseq,				/* Last good packet # we received */
 3283        		his_rseq,			/* Last good packet # HE received */
 3284        		wseq;				/* Next packet # we will send */
 3285        	
 3286        	int	last_op;			/* Last data op: OP_READ or OP_WRITE */
 3287        	#define	OP_READ		0
 3288        	#define	OP_WRITE	1
 3289        	
 3290        	int	reject;				/* Packet # to reject or NOREJECT */
 3291        	#define	NOREJECT	-1
 3292        	
 3293        	/* Segments are encoded as (log2 length) - 3, except in INITB packet */
 3294        	#ifdef BUFFEREDIO
 3295   X    	int wndsiz = 7;			/* Ask them to send up to 7 packets */
 3296        	#else
 3297        	int wndsiz = 1;			/* Ask for window of 1 messages flying */
 3298        	#endif
 3299        	int segsiz = 2;			/* Ask for 64 byte messages */
 3300        	int sendseg = 2;		/* Size segments other guy wants to see */
 3301        	int sendwin = 1;		/* Size window other guy wants to see */
 3302        	
 3303        	int sendbytes;			/* sendseg, in bytes */
 3304        	
 3305        	int	segbytes[10] = {	/* K value (encoded segment size) */
 3306        			-1,		/* 0 */
 3307        			32,		/* 1 */
 3308        			64,		/* 2 */
 3309        			128,		/* 3 */
 3310        			256,		/* 4 */
 3311        			512,		/* 5 */
 3312        			1024,		/* 6 */
 3313        			2048,		/* 7 */
 3314        			4096,		/* 8 */
 3315        			0,		/* 9 = KCONTROL */
 3316        	};
 3317        	

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 6
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (4)

             	
 3318        	/*
 3319        	 * Low level output routines.  These send packets without checking
 3320        	 * whether they got properly received.
 3321        	 *
 3322        	 * writeframe():
 3323        	 *
 3324        	 * Finish off an outgoing frame in msgo and queue it up to be written
 3325        	 * to the serial port.
 3326        	 *
 3327        	 * This routine is called to send each and every packet.
 3328        	 */
 3329        	int
 3330        	writeframe(cksm)
 3331        		int cksm;
 3332        	{
 3333    1   		
 3334    1   		msgo[0] = DLE;
 3335    1   		msgo[2] = cksm;
 3336    1   		msgo[3] = cksm >> 8;
 3337    1   		msgo[5] = msgo[1] ^ msgo[2] ^ msgo[3] ^ msgo[4];
 3338    1   	
 3339    1   		if (DEBUG_LEVEL(9)) {
 3340    2   			int i, maxlen;
 3341    2   	
 3342    2   			printf("T ");
 3343    2   			maxlen = segbytes[msgo[LENBYTE]] + 6;
 3344    2   			for (i = 0; i < maxlen; i++)
 3345    2   				printf("%02x  ",msgo[i] & 0xFF);
 3346    2   			putchar('\n');
 3347    2   		}
 3348    1   		if (DEBUG_LEVEL(6)) {
 3349    2   			int t, x, y;
 3350    2   	
 3351    2   			t = msgo[CBYTE] >> 6;
 3352    2   			x = (msgo[CBYTE] >> 3) & 7;
 3353    2   			y = msgo[CBYTE] & 7;
 3354    2   			if (t == CONTROL)
 3355    2   				printf("Sent: CONTROL %s %d\n",
 3356    2   					ctrl_pr[x], y);
 3357    2   			else
 3358    2   				printf("Sent: %s %d %d\n",
 3359    2   					tt_pr[t], x, y);
 3360    2   		}
 3361    1   	
 3362    1   		/*
 3363    1   		 * In our window=1 implementation, we just queue the packet
 3364    1   		 * up for transmission here (by leaving it in msgo[]).  It
 3365    1   		 * will be written next time we go through inpkt().
 3366    1   		 */
 3367    1   		last_op = OP_WRITE;	/* Remember to avoid overwriting the packet */
 3368    1   		return 0;		/* Never aborts */
 3369    1   	}
 3370        	

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 7
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (5)

             	
 3371        	/* Send an ack */
 3372        	int
 3373        	ackmsg()
 3374        	{
 3375    1   	
 3376    1   		msgo[1] = KCONTROL;
 3377    1   		if (reject != NOREJECT)
 3378    1   			msgo[4] = (CONTROL << 6) | (RJ << 3) | reject;
 3379    1   		else
 3380    1   			msgo[4] = (CONTROL << 6) | (RR << 3) | rseq;
 3381    1   		reject = NOREJECT;
 3382    1   		return writeframe((int)(MAGIC - msgo[4]));
 3383    1   	}
 3384        	
 3385        	
 3386        	/* Send a control message other than an ack */
 3387        	int
 3388        	ctlmsg(byte)
 3389        	char byte;
 3390        	{
 3391    1   	
 3392    1   		msgo[1] = KCONTROL;
 3393    1   		msgo[4] = (CONTROL << 6) | byte;
 3394    1   		return writeframe((int)(MAGIC - msgo[4]));
 3395    1   	}
 3396        	

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 8
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (6)

             	
 3397        	/*
 3398        	 * Medium level output routine.  This sends a short or long data packet
 3399        	 * and figures out when to retransmit and/or insert acknowledgements as
 3400        	 * needed.
 3401        	 */
 3402        	sendpacket(s, n, sorl)
 3403        		char *s;
 3404        		int n;
 3405        		int sorl;			/* SHORTDATA or LONGDATA */
 3406        	{
 3407    1   		int cksm, offset, difflen;
 3408    1   	
 3409    1   		if (last_op == OP_WRITE) {
 3410    2   			/* Better get the first one sent and ack'd first */
 3411    2   			/* FIXME, this will change for window > 1 */
 3412    2   			if (inpkt()) return 1;
 3413    2   		}
 3414    1   	
 3415    1   		bzero((char *)(msgo+6), sendbytes);
 3416    1   		msgo[1] = sendseg;
 3417    1   		msgo[4] = (sorl << 6) + (wseq << 3) + rseq;
 3418    1   	
 3419    1   		switch(sorl) {
 3420    2   		case LONGDATA:
 3421    2   			if (n > sendbytes) abort();
 3422    2   			offset = 6;
 3423    2   			break;
 3424    2   	
 3425    2   		case SHORTDATA:
 3426    2   			difflen = sendbytes - n;
 3427    2   			if (difflen < 1) abort();
 3428    2   			offset = 7;
 3429    2   			if (difflen <= 127) {
 3430    3   				msgo[6] = difflen;	  /* One byte count */
 3431    3   			} else {
 3432    3   				msgo[6] = 128 | difflen;  /* low byte, with 0x80 on */
 3433    3   				msgo[7] = difflen >> 7;   /* High byte */
 3434    3   				offset = 8;
 3435    3   			}
 3436    2   		}
 3437    1   	
 3438    1   		bcopy(s, msgo+offset, n);		/* Move the data */
 3439    1   	
 3440    1   		cksm = MAGIC - (chksum(&msgo[6], sendbytes) ^ (0377 & msgo[4]));
 3441    1   		wseq = (wseq + 1) & 7;			/* Bump sent pkt sequence # */
 3442    1   		return writeframe(cksm);
 3443    1   	}
 3444        	

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 9
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (7)

             	
 3445        	/*
 3446        	 * Medium level input routine.
 3447        	 *
 3448        	 * Write a packet to the serial port, then read a packet from the serial port.
 3449        	 * Return 1 if other side went away, 0 if good packet received.
 3450        	 *
 3451        	 * With window size of 1, we send a packet and then receive one.
 3452        	 * FIXME, when we implement a larger window size, this routine will become
 3453        	 * more complicated and callers will not be able to depend on msgo[]
 3454        	 * being sent and acknowledged when it returns.
 3455        	 */
 3456        	int
 3457        	inpkt()
 3458        	{
 3459    1   		int data,count,need;
 3460    1   		register int i;
 3461    1   		unsigned short pktsum, oursum;
 3462    1   		int status;
 3463    1   		/*
 3464    1   		 * Next vars are for re-queueing received chars to rescan them
 3465    1   		 * for a valid packet after an error.
 3466    1   		 */
 3467    1   		int queued = -1;  /* <0: off, 0: just finished, >0: # chars pending */
 3468    1   		unsigned char *qp;
 3469    1   		unsigned char qbuf[sizeof msgi];	/* This can be static if 4K
 3470    1   							   on the stack is too much */
 3471    1   	#	define	bad(str) {if (DEBUG_LEVEL(5)) printf str; goto oops; }
 3472    1   	
 3473    1   		if (firstslave) {
 3474    2   			firstslave = 0;
 3475    2   			goto again;
 3476    2   		}
 3477    1   	
 3478    1   	xmit:
 3479    1   		i = segbytes[msgo[LENBYTE]] + 6;
 3480    1   		status = xwrite(msgo,i);
 3481    1   		if (status != i) {
 3482    2   			if (DEBUG_LEVEL(0)) {
 3483    3   				printf("xmit %d bytes failed, status %d, errno %d", 
 3484    3   					i, status, errno);
 3485    3   			}
 3486    2   			return 1;		/* Write failed */
 3487    2   		}
 3488    1   	
 3489    1   	again:
 3490    1   		count = 0;
 3491    1   	
 3492    1   		DEBUG(9, "R ", 0);
 3493    1   	
 3494    1   		while (1) {
 3495    2   			if (queued >= 0) {
 3496    3   				/*
 3497    3   				 * Process some stuff from a string.
 3498    3   				 * If we just finished the last char queued, and
 3499    3   				 * we are still scanning for a DLE, re-xmit our
 3500    3   				 * last packet before we continue reading.

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 10
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (7)

 3501    3   				 * On the other hand, if we have a valid packet
 3502    3   				 * header accumulating, just keep reading the serial
 3503    3   				 * port.
 3504    3   				 */
 3505    3   				if (--queued < 0) {
 3506    4   					if (count == 0) {
 3507    5   						DEBUG(6, "End queue.  Re-xmit.\n", 0);
 3508    5   						goto xmit; /* No packet comin' in */
 3509    5   					} else {
 3510    5   						DEBUG(6,"End queue.  Keep reading\n",0);
 3511    5   						goto readser; /* Seems to be sumpin' */
 3512    5   					}
 3513    4   				}
 3514    3   				data = *qp++;		/* Just grab from queue */
 3515    3   			} else {
 3516    3   	readser:
 3517    3   				data = xgetc();
 3518    3   				if (data == EOF) break;
 3519    3   			}
 3520    2   	
 3521    2   			if (DEBUG_LEVEL(9))
 3522    2   				printf("%02x%c ",data & 0xFF, isprint(data)? data: ' ');
 3523    2   	
 3524    2   			switch (count)
 3525    2   			{
 3526    3   			case 0:
 3527    3   				/* Look for DLE */
 3528    3   				if (data == DLE)
 3529    3   					msgi[count++] = DLE;
 3530    3   				break;
 3531    3   	
 3532    3   			case LENBYTE:
 3533    3   				/* Check length byte */
 3534    3   				if (data > KCONTROL || data == 0)
 3535    3   					bad(("packet size"));
 3536    3   				if (segbytes[data] > MAX_PACKET) {
 3537    4   					bad(("packet too long for buffer"));
 3538    4   			oops:
 3539    4   					if (DEBUG_LEVEL(5))
 3540    4   						printf(" bad in above packet\n");
 3541    4   	
 3542    4   					/* FIXME, decode packet header here,
 3543    4   					   if enough of it has come in. */
 3544    4   	
 3545    4   					/* See if any DLEs in the bad packet */
 3546    4   					/* Skip 0, we know that's a DLE */
 3547    4   					for (i = 1; i < count; i++) {
 3548    5   						if (msgi[i] == DLE) {
 3549    6   							/* Reprocess from the DLE.
 3550    6   							 * if queued, back up the q.
 3551    6   							 * if not, make one.
 3552    6   							 */
 3553    6   							if (queued >= 0) {
 3554    7   								queued += count - i;
 3555    7   								qp -= count - i;
 3556    7   						DEBUG(6,"Backup and rescan queue\n", 0);
 3557    7   							} else {

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 11
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (7)

 3558    7   								bcopy(msgi+i, qbuf, 
 3559    7   									count - i);
 3560    7   								qp = qbuf;
 3561    7   								queued = count - i;
 3562    7   						DEBUG(6,"Queue and rescan input\n", 0);
 3563    7   							}
 3564    6   							goto again;
 3565    6   						}
 3566    5   					}
 3567    4   	
 3568    4   					if (queued >= 0) {
 3569    5   						DEBUG(6, "Continue scan\n", 0);
 3570    5   						goto again;
 3571    5   					} else {
 3572    5   						DEBUG(6, "Re-xmit previous packet\n",0);
 3573    5   						goto xmit;	/* Xmit then rcv */
 3574    5   					}
 3575    4   				}
 3576    3   				msgi[count++] = data;		/* Save it */
 3577    3   				msgsize = segbytes[data];	/* Save Packet size */
 3578    3   				need = 6 + msgsize;
 3579    3   				break;
 3580    3   	
 3581    3   			case CBYTE:
 3582    3   				/* Break up control byte as well as storing it */
 3583    3   				msgi[count++] = data;		/* Save it */
 3584    3   				tt = (data >> 6) & 3;
 3585    3   				xxx = (data >> 3) & 7;
 3586    3   				yyy = data & 7;
 3587    3   	
 3588    3   				/* Now check it a bit */
 3589    3   				switch (tt) {		/* Switch on msg type */
 3590    4   				case CONTROL:
 3591    4   					/* Control msg must have KCONTROL size */
 3592    4   					if (msgsize != 0) bad(("K versus Control"));
 3593    4   					/* We don't implement SRJ, nor does Unix */
 3594    4   					switch (xxx) {
 3595    5   					case SRJ:
 3596    5   						bad(("SRJ received"));
 3597    5   					case RJ:
 3598    5   					case RR:
 3599    5   						if (yyy != (7 & (wseq - 1)))
 3600    5   							bad(("didn't ack our pkt"));
 3601    5   					}
 3602    4   					break;
 3603    4   				
 3604    4   				case ALTCHN:
 3605    4   					bad(("ALTCHN received")); /* Unsupported */
 3606    4   	
 3607    4   				case SHORTDATA:
 3608    4   				case LONGDATA:
 3609    4   					if (msgsize == 0) bad (("KCONTROL with data"));
 3610    4   					if (((xxx - rseq) & 7) > wndsiz) {
 3611    5   						/* Atari ST cpp has problems with
 3612    5   						 * macro args broken across lines?
 3613    5   						 * That's why funny indent here
 3614    5   						 */

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 12
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (7)

 3615    5   	bad (("data out of window, xxx=%d rseq=%d", xxx, rseq));
 3616    5   					}
 3617    4   					/* FIXME, below enforces window size == 1 */
 3618    4   					/* Note that this is also how we guarantee
 3619    4   					   that msgo has been received OK by the time
 3620    4   					   we exit inpkt() too.  Don't change it unless
 3621    4   					   you know what you are doing. */
 3622    4   					if (yyy != (7 & (wseq - 1)))
 3623    4   						bad(("didn't ack our pkt"));
 3624    4   					break;
 3625    4   				}
 3626    3   				break;
 3627    3   	
 3628    3   			case FRAMEBYTE:
 3629    3   				/* See whole frame, check it a bit. */
 3630    3   				msgi[count++] = data;
 3631    3   				if (data != (msgi[1] ^ msgi[2] ^ msgi[3] ^ msgi[4]))
 3632    3   					bad(("frame checksum"));
 3633    3   				pktsum = msgi[2] + (msgi[3] << 8);
 3634    3   	
 3635    3   				if (tt == CONTROL) {
 3636    4   					/* Check checksums for control packets */
 3637    4   					oursum = MAGIC - msgi[4];
 3638    4   					if (pktsum != oursum)
 3639    4   						bad(("control checksum"));
 3640    4   					/*
 3641    4   					 * We have a full control packet.
 3642    4   					 * Update received seq number for the ones
 3643    4   					 * that carry one.
 3644    4   					 */
 3645    4   					switch (xxx) {
 3646    5   					case RJ: case RR:
 3647    5   						if (((wseq - yyy) & 7) > sendwin) {
 3648    6   	bad (("RJ/RR out of window, yyy=%d wseq=%d", yyy, wseq));
 3649    6   						}
 3650    5   						his_rseq = yyy;
 3651    5   					}
 3652    4   					goto done;
 3653    4   				} else {
 3654    4   					/*
 3655    4   					 * Received frame of data packet.
 3656    4   					 *
 3657    4   					 * Now that the checksum has been verified,
 3658    4   					 * we can believe the acknowledgement (if
 3659    4   					 * any) in it.
 3660    4   					 */
 3661    4   					if (((wseq - yyy) & 7) > sendwin) {
 3662    5   	bad (("data ack out of window, yyy=%d wseq=%d", yyy, wseq));
 3663    5   					}
 3664    4   					his_rseq = yyy;
 3665    4   				}
 3666    3   				break;
 3667    3   	
 3668    3   			default:
 3669    3   				msgi[count++] = data;
 3670    3   				if (count >= need) {
 3671    4   					/* We have received a full data packet */

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 13
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (7)

 3672    4   					oursum = MAGIC - (chksum(&msgi[6], sendbytes)
 3673    4   							  ^ (0377 & msgi[4]));
 3674    4   					if (pktsum != oursum) {
 3675    5   						/* Send a reject on this pkt */
 3676    5   						reject = xxx - 1;
 3677    5   	bad(("\ndata checksum in packet %x, ours=%x", pktsum, oursum));
 3678    5   					}
 3679    4   					/* FIXME, this may change for window>1 */
 3680    4   					if (xxx != (rseq+1)%8 ) {
 3681    5   	bad(("Not next packet xxx=%d rseq=%d", xxx, rseq));
 3682    5   					}
 3683    4   					rseq = xxx;	/* We saw this pkt OK */
 3684    4   			done:
 3685    4   					if (DEBUG_LEVEL(9))
 3686    4   						putchar('\n');
 3687    4   					if (DEBUG_LEVEL(6)) {
 3688    5   						if (tt == CONTROL)
 3689    5   							printf("Rcvd: CONTROL %s %d\n",
 3690    5   								ctrl_pr[xxx], yyy);
 3691    5   						else
 3692    5   							printf("Rcvd: %s %d %d\n",
 3693    5   								tt_pr[tt], xxx, yyy);
 3694    5   					}
 3695    4   					last_op = OP_READ;
 3696    4   					return(0);
 3697    4   				}
 3698    3   				break;
 3699    3   			}
 3700    2   		}
 3701    1   		DEBUG(6, " EOF\n", 0);
 3702    1   		return(1);
 3703    1   	}
 3704        	

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 14
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (8)

             	
 3705        	int
 3706        	chksum(s,n)
 3707        	register unsigned char *s;
 3708        	register n;
 3709        	{
 3710    1   		register short sum;
 3711    1   		register unsigned short t;
 3712    1   		register short x;
 3713    1   	
 3714    1   		sum = -1;
 3715    1   		x = 0;
 3716    1   		do {
 3717    2   			if (sum < 0)
 3718    2   			{
 3719    3   				sum <<= 1;
 3720    3   				sum++;
 3721    3   			}
 3722    2   			else
 3723    2   				sum <<= 1;
 3724    2   			t = sum;
 3725    2   			sum += *s++ & 0377;
 3726    2   			x += sum ^ n;
 3727    2   			if ((unsigned short)sum <= t)
 3728    2   				sum ^= x;
 3729    2   		} while (--n > 0);
 3730    1   	
 3731    1   		return(sum);
 3732    1   	}
 3733        	

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 15
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (9)

             	
 3734        	/*
 3735        	 * Medium level packet driver input routine.
 3736        	 *
 3737        	 * Read a data packet from the other side.  If called twice in succession,
 3738        	 * we send an ack of the previous packet.  Otherwise we tend to piggyback
 3739        	 * the acks on data packets.
 3740        	 *
 3741        	 * Result is 0 if we got a data packet, 1 if we got some other kind, or
 3742        	 * a hangup timeout.
 3743        	 */
 3744        	int
 3745        	indata()
 3746        	{
 3747    1   	
 3748    1   		while (1) {
 3749    2   			if (last_op == OP_READ) {
 3750    3   				ackmsg();		/* Send an ack */
 3751    3   			}
 3752    2   			if (inpkt()) return 1;
 3753    2   	
 3754    2   			switch (tt) {
 3755    3   			case ALTCHN:
 3756    3   				return 1;		/* Unsupported - yet */
 3757    3   	
 3758    3   			case LONGDATA:
 3759    3   			case SHORTDATA:
 3760    3   				/*
 3761    3   				 * We got a data packet.  That's what we want,
 3762    3   				 * so return.
 3763    3   				 */
 3764    3   				return 0;		/* We are done. */
 3765    3   	
 3766    3   			case CONTROL:	
 3767    3   				switch (xxx) {
 3768    4   				default:
 3769    4   					return 1;	/* Bad packet type */
 3770    4   	
 3771    4   				case RJ:		/* Reject prev pkt */
 3772    4   				case RR:		/* OK but no data */
 3773    4   					break;		/* Ack and try again */
 3774    4   				}
 3775    3   			}
 3776    2   		}
 3777    1   	}
 3778        	

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 16
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (10)

             	
 3779        	/*
 3780        	 * Open a conversation in the g protocol.  Medium level routine.
 3781        	 *
 3782        	 * We need to both send and receive each packet type in turn.
 3783        	 * If this sequence falters, we start over at INITA, trying a few more times.
 3784        	 *
 3785        	 * Returns 0 for success, 1 for failure.
 3786        	 */
 3787        	int
 3788        	gturnon(mastermode)
 3789        		int mastermode;
 3790        	{
 3791    1   		int tries = 0;
 3792    1   		int step = 0;
 3793    1   		static int which[] = {INITA, INITA, INITB, INITB, INITC, INITC};
 3794    1   	
 3795    1   		/* initialize protocol globals, e.g. packet sequence numbers */
 3796    1   	
 3797    1   		rseq = 0;		/* Last good packet # we have seen from him */
 3798    1   		wseq = 1;		/* Next packet # we will send */
 3799    1   		his_rseq = 0;		/* Last good Packet # he has seen from us */
 3800    1   		reject = NOREJECT;	/* Don't reject first packet */
 3801    1   		firstslave = mastermode? 0: 1;	/* About to do first slave packet? */
 3802    1   	
 3803    1   		if (mastermode) goto master_start;
 3804    1   	
 3805    1   		while (++tries <= 8) {
 3806    2   			/* Receive an initialization packet and handle it */
 3807    2   			if (inpkt() == 0 && tt == CONTROL && xxx == which[step]) {
 3808    3   				switch (xxx) {
 3809    4   				/* Remember we've seen it, grab value */
 3810    4   				case INITA:
 3811    4   				do_inita:
 3812    4   					sendwin = yyy;
 3813    4   					break;
 3814    4   				case INITB:
 3815    4   					/*
 3816    4   					 * Get preferred packet size for other guy,
 3817    4   					 * but don't overrun our buffer space.
 3818    4   					 * The encoded segment size is off-by-1 from
 3819    4   					 * the one used in the K field in each packet.
 3820    4   					 */
 3821    4   					do {
 3822    5   						sendseg = yyy+1;
 3823    5   						sendbytes = segbytes[sendseg];
 3824    5   					} while (sendbytes > MAX_PACKET && --yyy);
 3825    4   					break;
 3826    4   				case INITC:
 3827    4   					sendwin = yyy;
 3828    4   					break;
 3829    4   				}
 3830    3   				if (++step >= 6)		/* Move forward */
 3831    3   					return 0;		/* We are done */
 3832    3   			} else {
 3833    3   				/* Start over, sigh */
 3834    3   				/* We don't handle the hangup condition well here;

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 17
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (10)

 3835    3   				 * we should giveup completely instead of trying
 3836    3   				 * again.  FIXME.  -- JEH */
 3837    3   				step = 0;
 3838    3   				if (xxx == INITA)	/* Start with his inita */
 3839    3   					goto do_inita;
 3840    3   			}
 3841    2   	
 3842    2   	master_start:
 3843    2   			/*
 3844    2   			 * Transmit an initialization packet.
 3845    2   			 */
 3846    2   			switch (which[step]) {
 3847    3   			case INITA:
 3848    3   				ctlmsg((INITA << 3) | wndsiz);
 3849    3   				break;
 3850    3   			case INITB:
 3851    3   				ctlmsg((INITB << 3) | (segsiz - 1));
 3852    3   				break;
 3853    3   			case INITC:
 3854    3   				ctlmsg((INITC << 3) | wndsiz);
 3855    3   				break;
 3856    3   			}
 3857    2   			if (++step >= 6)
 3858    2   				return 0;		/* We are done */
 3859    2   		}
 3860    1   		return 1;				/* Failure */
 3861    1   	}
 3862        	

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 18
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (11)

             	
 3863        	/*
 3864        	 * Turn off conversation in the G protocol.  Medium level routine.
 3865        	 */
 3866        	int
 3867        	gturnoff()
 3868        	{
 3869    1   	
 3870    1   		/* In windowed protocol, we have to check if prev one's been ack'd */
 3871    1   		if (last_op == OP_WRITE) {
 3872    2   			if (inpkt()) return 1;
 3873    2   		}
 3874    1   	
 3875    1   		do {
 3876    2   			ctlmsg(CLOSE << 3);
 3877    2   			if (inpkt())
 3878    2   				return 1;
 3879    2   		} while (tt != CONTROL && xxx != CLOSE);
 3880    1   	
 3881    1   		return 0;
 3882    1   	}
 3883        	

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 19
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (12)

             	
 3884        	/*
 3885        	 * Read a message from the other side.
 3886        	 *
 3887        	 * Messages are always contained in LONGDATA packets.  If a message is
 3888        	 * longer than a single packet, only the last packet will contain a null
 3889        	 * character.  Keep catenating them until you see the null.
 3890        	 *
 3891        	 * Return SUCCESS or FAIL.  If the received message is longer than our
 3892        	 * buffer, we eat the whole message, but return FAIL once it ends.
 3893        	 */
 3894        	int
 3895        	grdmsg(str, fn)
 3896        		char *str;	/* Buffer to put it in, sized MAXMSGLEN */
 3897        		int fn;		/* File descriptor to read it from */
 3898        	{
 3899    1   		unsigned msglen;
 3900    1   		unsigned totlen = 0;
 3901    1   		unsigned oldlen;
 3902    1   	
 3903    1   		str[0] = '\0';		/* No command yet */
 3904    1   		do {
 3905    2   			if (indata() || tt != LONGDATA)
 3906    2   				return FAIL;
 3907    2   			msgi[6+msgsize] = '\0';	/* Null terminate packet */
 3908    2   			msglen = strlen(msgi+6);
 3909    2   			oldlen = totlen;
 3910    2   			totlen += msglen;
 3911    2   			if (totlen < MAXMSGLEN) {
 3912    3   				strcat(str+oldlen,&msgi[6]);  /* Tack on to command */
 3913    3   			}
 3914    2   		} while (msglen == msgsize);	/* Loop if no null in pkt */
 3915    1   	
 3916    1   		return (totlen < MAXMSGLEN)? SUCCESS: FAIL;
 3917    1   	}
 3918        	
 3919        	
 3920        	/*
 3921        	 * Write a message to the other side.
 3922        	 *
 3923        	 * We write the first (or only) packet from our local bufr[], the
 3924        	 * rest comes straight out of the caller's string.
 3925        	 */
 3926        	int
 3927        	gwrmsg(type, str, fn)
 3928        		char type;
 3929        		char *str;
 3930        		int fn;
 3931        	{
 3932    1   		char bufr[MAX_PACKET];
 3933    1   		char *ptr;
 3934    1   		int thislen, totlen;
 3935    1   		
 3936    1   		bufr[0] = type;
 3937    1   		totlen = strlen(str) + 1;
 3938    1   		if (totlen > MAXMSGLEN) abort();
 3939    1   		strncpy(&bufr[1], str, sendbytes-1);

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 20
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (12)

 3940    1   		ptr = bufr;
 3941    1   		
 3942    1   		for (;;) {
 3943    2   			thislen = totlen;
 3944    2   			if (thislen > sendbytes) thislen = sendbytes;
 3945    2   			if (sendpacket(ptr, thislen, LONGDATA))
 3946    2   				return FAIL;
 3947    2   			totlen -= sendbytes;
 3948    2   			if (totlen < 0) break;
 3949    2   			if (ptr == bufr)	ptr = str + (sendbytes - 1);
 3950    2   			else			ptr += sendbytes;
 3951    2   		}
 3952    1   	
 3953    1   		return SUCCESS;
 3954    1   	}
 3955        	
 3956        	/*
 3957        	 * Write a file to the other side.
 3958        	 */
 3959        	int
 3960        	gwrdata(file, fn)
 3961        		FILE *file;		/* File to be sent */
 3962        		int fn;			/* fd of serial line */
 3963        	{
 3964    1   		char dskbuf[MAX_PACKET];	/* Disk I/O buffer */
 3965    1   		int count;
 3966    1   	
 3967    1   		do {
 3968    2   			count = fread(dskbuf, sizeof (char), sendbytes, file);
 3969    2   			if (count < 0) return FAIL;	/* FIXME, should send EOF */
 3970    2   			if (sendpacket(dskbuf, count,
 3971    2   				(count == sendbytes)? LONGDATA: SHORTDATA))
 3972    2   					return FAIL;
 3973    2   		} while (count);
 3974    1   	
 3975    1   		return SUCCESS;
 3976    1   	}
 3977        	
 3978        	/*
 3979        	 * Read a file from the other side.
 3980        	 */
 3981        	int
 3982        	grddata(fn, file)
 3983        		int fn;			/* File desc of serial line */
 3984        		FILE *file;		/* stdio file ptr of file to read into */
 3985        	{
 3986    1   		int offset;
 3987    1   		int status;
 3988    1   		int error = 0;
 3989    1   	
 3990    1   		do {
 3991    2   			/* Read a packet, handle the data in it */
 3992    2   			if (indata())
 3993    2   				return FAIL;
 3994    2   	
 3995    2   			switch (tt) {
 3996    3   			case LONGDATA:

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 21
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (12)

 3997    3   				/* FIXME, check this write */
 3998    3   				offset = 6;
 3999    3   				goto writeit;
 4000    3   			case SHORTDATA:
 4001    3   				if (msgi[6] & 0x80) {
 4002    4   					msgsize -=
 4003    4   					  (msgi[7] << 7) | (127&msgi[6]);
 4004    4   					offset = 8;
 4005    4   				} else {
 4006    4   					msgsize -= msgi[6];
 4007    4   					offset = 7;
 4008    4   				}
 4009    3   	
 4010    3   			writeit:
 4011    3   				/* FIXME:
 4012    3   				 * Consider skipping further writing if error != 0 */
 4013    3   				if (msgsize != 0) {
 4014    4   					status = fwrite(&msgi[offset], sizeof (char),
 4015    4   							msgsize, file);
 4016    4   					if (status != msgsize) error++;
 4017    4   				}
 4018    3   				break;
 4019    3   			}
 4020    2   		} while (msgsize != 0);
 4021    1   	
 4022    1   		return error? FAIL: SUCCESS;
 4023    1   	}


GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 22
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (12)

                                       +-------------+
                                       | Storage Map |
                                       +-------------+
 
 

External Declarations
---------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

abort                            2356                    Extern       Void function
ackmsg                           3373                    Extern def.  Function returning long int
CABS_T                           1495    16 bytes                     Structure tag
 x                               1495    1 quadword                    Member (offset = 0), double
 y                               1495    1 quadword                    Member (offset = 8 bytes), double
clock_t                          2527    1 longword                   Typedef:  long int
ctlmsg                           3388                    Extern def.  Function returning long int
ctrl_pr                          3262    8 longwords     Extern def.  Initialized array [8] of pointer to char
debug                            2987    1 longword      Extern       Long int
dev_t                            2267    1 longword                   Typedef:  pointer to char
errno                            3137    1 longword      Extern       Long int
FILE                             2424    1 longword                   Typedef:  pointer to struct _iobuf
firstslave                       3279    1 longword      Extern def.  Long int
fputc                            2498                    Extern       Function returning long int
fread                            2482                    Extern       Function returning long int
fwrite                           2485                    Extern       Function returning long int
his_rseq                         3283    1 longword      Extern def.  Long int
indata                           3745                    Extern def.  Function returning long int
ino_t                            2266    1 word                       Typedef:  unsigned short int
inpkt                            3457                    Extern def.  Function returning long int
jmp_buf                          1745    15 longwords                 Typedef:  array [15] of long int
last_op                          3286    1 longword      Extern def.  Long int
msgi                             3276    4106 bytes      Extern def.  Array [4106] of unsigned char
msgo                             3277    4106 bytes      Extern def.  Array [4106] of unsigned char
msgsize                          3280    1 longword      Extern def.  Long int
off_t                            2265    1 longword                   Typedef:  unsigned long int
port                             3011    68 bytes                     Structure tag
 portname                        3012    20 bytes                      Member (offset = 0), array [20] of char
 modemname                       3013    20 bytes                      Member (offset = 20 bytes), array [20] of char
 devname                         3014    20 bytes                      Member (offset = 40 bytes), array [20] of char
 baud                            3015    1 longword                    Member (offset = 60 bytes), long int
 chain                           3016    1 longword                    Member (offset = 64 bytes), pointer to struct port
printf                           2495                    Extern       Function returning long int
reject                           3290    1 longword      Extern def.  Long int
rseq                             3282    1 longword      Extern def.  Long int
segbytes                         3305    10 longwords    Extern def.  Initialized array [10] of long int
segsiz                           3299    1 longword      Extern def.  Initialized long int
sendbytes                        3303    1 longword      Extern def.  Long int
sendpacket                       3402                    Extern def.  Function returning long int
sendseg                          3300    1 longword      Extern def.  Initialized long int
sendwin                          3301    1 longword      Extern def.  Initialized long int
sigstack                         1811    8 bytes                      Structure tag
 ss_sp                           1813    1 longword                    Member (offset = 0), pointer to char
 ss_onstack                      1814    1 longword                    Member (offset = 4 bytes), long int
sigvec                           1795    12 bytes                     Structure tag

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 23
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (12)

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

 sv_handler                      1797    1 longword                    Member (offset = 0), pointer to function returning long int
 sv_mask                         1798    1 longword                    Member (offset = 4 bytes), long int
 sv_onstack                      1799    1 longword                    Member (offset = 8 bytes), long int
stdout                           2425    1 longword      Extern       Noshare pointer to pointer to struct _iobuf
strcat                           2827                    Extern       Function returning pointer to char
strlen                           2851                    Extern       Function returning long int
strncpy                          2825                    Extern       Function returning pointer to char
tbuffer                          2538    16 bytes                     Structure tag
 proc_user_time                  2540    1 longword                    Member (offset = 0), long int
 proc_system_time                2540    1 longword                    Member (offset = 4 bytes), long int
 child_user_time                 2541    1 longword                    Member (offset = 8 bytes), long int
 child_system_time               2541    1 longword                    Member (offset = 12 bytes), long int
tbuffer_t                        2544    16 bytes                     Typedef:  struct tbuffer
timeb                            2560    10 bytes                     Structure tag
 time                            2562    1 longword                    Member (offset = 0), long int
 millitm                         2563    1 word                        Member (offset = 4 bytes), unsigned short int
 timezone                        2564    1 word                        Member (offset = 6 bytes), short int
 dstflag                         2565    1 word                        Member (offset = 8 bytes), short int
timeb_t                          2568    10 bytes                     Typedef:  struct timeb
time_t                           2533    1 longword                   Typedef:  long int
tm                               2572    36 bytes                     Structure tag
 tm_sec                          2574    1 longword                    Member (offset = 0), long int
 tm_min                          2574    1 longword                    Member (offset = 4 bytes), long int
 tm_hour                         2574    1 longword                    Member (offset = 8 bytes), long int
 tm_mday                         2575    1 longword                    Member (offset = 12 bytes), long int
 tm_mon                          2575    1 longword                    Member (offset = 16 bytes), long int
 tm_year                         2575    1 longword                    Member (offset = 20 bytes), long int
 tm_wday                         2576    1 longword                    Member (offset = 24 bytes), long int
 tm_yday                         2576    1 longword                    Member (offset = 28 bytes), long int
 tm_isdst                        2576    1 longword                    Member (offset = 32 bytes), long int
tm_t                             2579    36 bytes                     Typedef:  struct tm
tt                               3281    1 longword      Extern def.  Long int
tt_pr                            3248    4 longwords     Extern def.  Initialized array [4] of pointer to char
wndsiz                           3297    1 longword      Extern def.  Initialized long int
writeframe                       3330                    Extern def.  Function returning long int
wseq                             3284    1 longword      Extern def.  Long int
xgetc                            3068                    Extern       Function returning long int
xwrite                           3067                    Extern       Function returning long int
xxx                              3281    1 longword      Extern def.  Long int
yyy                              3281    1 longword      Extern def.  Long int
_ctype_                          158     byte            Extern       Const array of char
_iobuf                           2404    14 bytes                     Structure tag
 _cnt                            2406    1 longword                    Member (offset = 0), long int
 _ptr                            2407    1 longword                    Member (offset = 4 bytes), pointer to char
 _base                           2408    1 longword                    Member (offset = 8 bytes), pointer to char
 _flag                           2409    1 byte                        Member (offset = 12 bytes), char
 _file                           2420    1 byte                        Member (offset = 13 bytes), char
 
 

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 24
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (12)


Function "writeframe" defined at line 3330
------------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

cksm                             3331    1 longword                   Parameter # 1, long int
i                                3340    1 longword      Register     Long int
maxlen                           3340    1 longword      Register     Long int
t                                3349    1 longword      Not Alloc.   Long int
x                                3349    1 longword      Not Alloc.   Long int
y                                3349    1 longword      Not Alloc.   Long int
 
 

Function "ackmsg" defined at line 3373
--------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

No names declared
 
 

Function "ctlmsg" defined at line 3388
--------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

byte                             3389    1 byte                       Parameter # 1, char
 
 

Function "sendpacket" defined at line 3402
------------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

bcopy                            3438                    Extern       Function returning long int
bzero                            3415                    Extern       Function returning long int
chksum                           3440                    Extern       Function returning long int
cksm                             3407    1 longword      Not Alloc.   Long int
difflen                          3407    1 longword      Register     Long int
inpkt                            3412                    Extern       Function returning long int
n                                3404    1 longword                   Parameter # 2, long int
offset                           3407    1 longword      Register     Long int
s                                3403    1 longword                   Parameter # 1, pointer to char
sorl                             3405    1 longword                   Parameter # 3, long int
 
 

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 25
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (12)


Function "inpkt" defined at line 3457
-------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

again                            3489                                 Label
bcopy                            3558                    Extern       Function returning long int
chksum                           3672                    Extern       Function returning long int
count                            3459    1 longword      Register     Long int
data                             3459    1 longword      Register     Long int
done                             3684                                 Label
i                                3460    1 longword      Register     Long int
need                             3459    1 longword      Auto         Long int
oops                             3538                                 Label
oursum                           3461    1 word          Auto         Unsigned short int
pktsum                           3461    1 word          Auto         Unsigned short int
qbuf                             3469    4106 bytes      Auto         Array [4106] of unsigned char
qp                               3468    1 longword      Register     Pointer to unsigned char
queued                           3467    1 longword      Register     Initialized long int
readser                          3516                                 Label
status                           3462    1 longword      Not Alloc.   Long int
xmit                             3478                                 Label
 
 

Function "chksum" defined at line 3706
--------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

n                                3708    1 longword      Register     Parameter # 2, long int
s                                3707    1 longword      Register     Parameter # 1, pointer to unsigned char
sum                              3710    1 word          Register     Short int
t                                3711    1 word          Register     Unsigned short int
x                                3712    1 word          Register     Short int
 
 

Function "indata" defined at line 3745
--------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

 
 

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 26
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (12)


Function "gturnon" defined at line 3788
---------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

do_inita                         3811                                 Label
mastermode                       3789    1 longword                   Parameter # 1, long int
master_start                     3842                                 Label
step                             3792    1 longword      Register     Initialized long int
tries                            3791    1 longword      Register     Initialized long int
which                            3793    6 longwords     Static       Initialized array [6] of long int
 
 

Function "gturnoff" defined at line 3867
----------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

No names declared
 
 

Function "grdmsg" defined at line 3895
--------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

msglen                           3899    1 longword      Register     Unsigned long int
oldlen                           3901    1 longword      Register     Unsigned long int
str                              3896    1 longword                   Parameter # 1, pointer to char
totlen                           3900    1 longword      Register     Initialized unsigned long int
 
 

Function "gwrmsg" defined at line 3927
--------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

bufr                             3932    4096 bytes      Auto         Array [4096] of char
ptr                              3933    1 longword      Register     Pointer to char
str                              3929    1 longword                   Parameter # 2, pointer to char
thislen                          3934    1 longword      Register     Long int
totlen                           3934    1 longword      Register     Long int
type                             3928    1 byte                       Parameter # 1, char
 
 

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 27
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (12)


Function "gwrdata" defined at line 3960
---------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

count                            3965    1 longword      Not Alloc.   Long int
dskbuf                           3964    4096 bytes      Auto         Array [4096] of char
file                             3961    1 longword                   Parameter # 1, pointer to pointer to struct _iobuf
 
 

Function "grddata" defined at line 3982
---------------------------------------

 Identifier Name                 Line    Size            Class        Type
 ---------------                 ----    ----            -----        ----

error                            3988    1 longword      Register     Initialized long int
file                             3984    1 longword                   Parameter # 2, pointer to pointer to struct _iobuf
offset                           3986    1 longword      Register     Long int
status                           3987    1 longword      Not Alloc.   Long int
writeit                          4010                                 Label
 
 

Psect Synopsis
--------------

 Psect Name                     Allocation  Attributes
 ----------                     ----------  ----------

$CODE                           3358 bytes  Position-independent, relocatable, shareable, executable, readable
$DATA                           24 bytes    Position-independent, relocatable, readable, writeable
GIO_VERSION                     31 bytes    Position-independent, overlay, relocatable, global, shareable, readable, writeable
_CTYPE_                         0           Position-independent, overlay, relocatable, global, shareable, readable
ERRNO                           4 bytes     Position-independent, overlay, relocatable, global, readable, writeable
VAXC$ERRNO                      4 bytes     Position-independent, overlay, relocatable, global, readable, writeable
STDIN                           4 bytes     Position-independent, overlay, relocatable, global, readable, writeable
STDOUT                          4 bytes     Position-independent, overlay, relocatable, global, readable, writeable
STDERR                          4 bytes     Position-independent, overlay, relocatable, global, readable, writeable
DEBUG                           4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
PROGNAME                        20 bytes    Position-independent, overlay, relocatable, global, shareable, readable, writeable
SPOOL                           4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
CONTROL                         4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
MYNAME                          20 bytes    Position-independent, overlay, relocatable, global, shareable, readable, writeable
HOST_NAME                       20 bytes    Position-independent, overlay, relocatable, global, shareable, readable, writeable
OURPID                          4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
SYSFILE                         4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
USERFILE                        4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
PUBDIR                          4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
PORTS                           4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
WHO                             255 bytes   Position-independent, overlay, relocatable, global, shareable, readable, writeable
LOGFD                           4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
SYSDEP_CONTROL                  0           Position-independent, overlay, relocatable, global, shareable, readable, writeable
TT_PR                           16 bytes    Position-independent, overlay, relocatable, global, shareable, readable, writeable

GIO                                                             12-NOV-1988 14:10:59    VAX C      V2.3-024                 Page 28
V1.0                                                            11-OCT-1988 15:53:56    DUA1:[VMSNET.DEVEL.GNUUCP.SRC]GIO.C;2 (12)

 Psect Name                     Allocation  Attributes
 ----------                     ----------  ----------

$CHAR_STRING_CONSTANTS          729 bytes   Position-independent, relocatable, readable, writeable
CTRL_PR                         32 bytes    Position-independent, overlay, relocatable, global, shareable, readable, writeable
MSGI                            4106 bytes  Position-independent, overlay, relocatable, global, shareable, readable, writeable
MSGO                            4106 bytes  Position-independent, overlay, relocatable, global, shareable, readable, writeable
FIRSTSLAVE                      4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
MSGSIZE                         4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
TT                              4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
XXX                             4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
YYY                             4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
RSEQ                            4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
HIS_RSEQ                        4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
WSEQ                            4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
LAST_OP                         4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
REJECT                          4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
WNDSIZ                          4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
SEGSIZ                          4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
SENDSEG                         4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
SENDWIN                         4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
SENDBYTES                       4 bytes     Position-independent, overlay, relocatable, global, shareable, readable, writeable
SEGBYTES                        40 bytes    Position-independent, overlay, relocatable, global, shareable, readable, writeable
 
 

Function Definition Map
-----------------------

 Line   Name
 ----   ----

3330    writeframe
3373    ackmsg
3388    ctlmsg
3402    sendpacket
3457    inpkt
3706    chksum
3745    indata
3788    gturnon
3867    gturnoff
3895    grdmsg
3927    gwrmsg
3960    gwrdata
3982    grddata
 
 
Command Line
------------
 
CC/LIST=[-.BLD]/OBJE=[-.BLD]/SHOW=(BRIEF,SOURCE,SYMBOLS)/DEFINE=LOG GIO

