xref: /csrg-svn/usr.bin/telnet/network.c (revision 65157)
133685Sbostic /*
262311Sbostic  * Copyright (c) 1988, 1993
362311Sbostic  *	The Regents of the University of California.  All rights reserved.
433685Sbostic  *
542770Sbostic  * %sccs.include.redist.c%
633685Sbostic  */
733685Sbostic 
833685Sbostic #ifndef lint
9*65157Sdab static char sccsid[] = "@(#)network.c	8.2 (Berkeley) 12/15/93";
1033685Sbostic #endif /* not lint */
1133685Sbostic 
1232146Sminshall #include <sys/types.h>
1332146Sminshall #include <sys/socket.h>
1432146Sminshall #include <sys/time.h>
1532146Sminshall 
1632146Sminshall #include <errno.h>
1732146Sminshall 
1832146Sminshall #include <arpa/telnet.h>
1932146Sminshall 
2032381Sminshall #include "ring.h"
2132381Sminshall 
2232146Sminshall #include "defines.h"
2332146Sminshall #include "externs.h"
2432667Sminshall #include "fdset.h"
2532146Sminshall 
2646808Sdab Ring		netoring, netiring;
2746808Sdab unsigned char	netobuf[2*BUFSIZ], netibuf[BUFSIZ];
2832146Sminshall 
2932146Sminshall /*
3032146Sminshall  * Initialize internal network data structures.
3132146Sminshall  */
3232146Sminshall 
3346808Sdab     void
init_network()3432146Sminshall init_network()
3532146Sminshall {
3634848Sminshall     if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) {
3734848Sminshall 	exit(1);
3834848Sminshall     }
3934848Sminshall     if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) {
4034848Sminshall 	exit(1);
4134848Sminshall     }
4232146Sminshall     NetTrace = stdout;
4332146Sminshall }
4432146Sminshall 
4532146Sminshall 
4632146Sminshall /*
4732146Sminshall  * Check to see if any out-of-band data exists on a socket (for
4832146Sminshall  * Telnet "synch" processing).
4932146Sminshall  */
5032146Sminshall 
5146808Sdab     int
stilloob()5232552Sminshall stilloob()
5332146Sminshall {
5432146Sminshall     static struct timeval timeout = { 0 };
5532146Sminshall     fd_set	excepts;
5632146Sminshall     int value;
5732146Sminshall 
5832146Sminshall     do {
5932146Sminshall 	FD_ZERO(&excepts);
6032552Sminshall 	FD_SET(net, &excepts);
6132552Sminshall 	value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
6232146Sminshall     } while ((value == -1) && (errno == EINTR));
6332146Sminshall 
6432146Sminshall     if (value < 0) {
6532146Sminshall 	perror("select");
6634848Sminshall 	(void) quit();
6744360Sborman 	/* NOTREACHED */
6832146Sminshall     }
6932552Sminshall     if (FD_ISSET(net, &excepts)) {
7032146Sminshall 	return 1;
7132146Sminshall     } else {
7232146Sminshall 	return 0;
7332146Sminshall     }
7432146Sminshall }
7532146Sminshall 
7632146Sminshall 
7732146Sminshall /*
7832257Sminshall  *  setneturg()
7932257Sminshall  *
8032257Sminshall  *	Sets "neturg" to the current location.
8132257Sminshall  */
8232257Sminshall 
8346808Sdab     void
setneturg()8432257Sminshall setneturg()
8532257Sminshall {
8632381Sminshall     ring_mark(&netoring);
8732257Sminshall }
8832257Sminshall 
8932257Sminshall 
9032257Sminshall /*
9132146Sminshall  *  netflush
9232146Sminshall  *		Send as much data as possible to the network,
9332146Sminshall  *	handling requests for urgent data.
9432146Sminshall  *
9532146Sminshall  *		The return value indicates whether we did any
9632146Sminshall  *	useful work.
9732146Sminshall  */
9832146Sminshall 
9932146Sminshall 
10046808Sdab     int
netflush()10132146Sminshall netflush()
10232146Sminshall {
10333294Sminshall     register int n, n1;
10432146Sminshall 
10560149Sdab #ifdef	ENCRYPTION
10646808Sdab     if (encrypt_output)
10746808Sdab 	ring_encrypt(&netoring, encrypt_output);
10860149Sdab #endif	/* ENCRYPTION */
10932667Sminshall     if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
11032381Sminshall 	if (!ring_at_mark(&netoring)) {
111*65157Sdab 	    n = send(net, (char *)netoring.consume, n, 0); /* normal write */
11232146Sminshall 	} else {
11332146Sminshall 	    /*
11432146Sminshall 	     * In 4.2 (and 4.3) systems, there is some question about
11532146Sminshall 	     * what byte in a sendOOB operation is the "OOB" data.
11632146Sminshall 	     * To make ourselves compatible, we only send ONE byte
11732146Sminshall 	     * out of band, the one WE THINK should be OOB (though
11832146Sminshall 	     * we really have more the TCP philosophy of urgent data
11932146Sminshall 	     * rather than the Unix philosophy of OOB data).
12032146Sminshall 	     */
121*65157Sdab 	    n = send(net, (char *)netoring.consume, 1, MSG_OOB);/* URGENT data */
12232146Sminshall 	}
12332146Sminshall     }
12432146Sminshall     if (n < 0) {
12532146Sminshall 	if (errno != ENOBUFS && errno != EWOULDBLOCK) {
12632146Sminshall 	    setcommandmode();
12732146Sminshall 	    perror(hostname);
12844360Sborman 	    (void)NetClose(net);
12932381Sminshall 	    ring_clear_mark(&netoring);
13032146Sminshall 	    longjmp(peerdied, -1);
13132146Sminshall 	    /*NOTREACHED*/
13232146Sminshall 	}
13332146Sminshall 	n = 0;
13432146Sminshall     }
13532146Sminshall     if (netdata && n) {
13632528Sminshall 	Dump('>', netoring.consume, n);
13732146Sminshall     }
13832667Sminshall     if (n) {
13933294Sminshall 	ring_consumed(&netoring, n);
14033294Sminshall 	/*
14133294Sminshall 	 * If we sent all, and more to send, then recurse to pick
14233294Sminshall 	 * up the other half.
14333294Sminshall 	 */
14433294Sminshall 	if ((n1 == n) && ring_full_consecutive(&netoring)) {
14533294Sminshall 	    (void) netflush();
14632667Sminshall 	}
14733294Sminshall 	return 1;
14833294Sminshall     } else {
14933294Sminshall 	return 0;
15032667Sminshall     }
15132146Sminshall }
152