xref: /csrg-svn/usr.bin/telnet/network.c (revision 42770)
133685Sbostic /*
233685Sbostic  * Copyright (c) 1988 Regents of the University of California.
333685Sbostic  * All rights reserved.
433685Sbostic  *
5*42770Sbostic  * %sccs.include.redist.c%
633685Sbostic  */
733685Sbostic 
833685Sbostic #ifndef lint
9*42770Sbostic static char sccsid[] = "@(#)network.c	1.14 (Berkeley) 06/01/90";
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 
2632531Sminshall Ring	netoring, netiring;
2732531Sminshall char	netobuf[2*BUFSIZ], netibuf[BUFSIZ];
2832146Sminshall 
2932146Sminshall /*
3032146Sminshall  * Initialize internal network data structures.
3132146Sminshall  */
3232146Sminshall 
3332146Sminshall init_network()
3432146Sminshall {
3534848Sminshall     if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) {
3634848Sminshall 	exit(1);
3734848Sminshall     }
3834848Sminshall     if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) {
3934848Sminshall 	exit(1);
4034848Sminshall     }
4132146Sminshall     NetTrace = stdout;
4232146Sminshall }
4332146Sminshall 
4432146Sminshall 
4532146Sminshall /*
4632146Sminshall  * Check to see if any out-of-band data exists on a socket (for
4732146Sminshall  * Telnet "synch" processing).
4832146Sminshall  */
4932146Sminshall 
5032146Sminshall int
5132552Sminshall stilloob()
5232146Sminshall {
5332146Sminshall     static struct timeval timeout = { 0 };
5432146Sminshall     fd_set	excepts;
5532146Sminshall     int value;
5632146Sminshall 
5732146Sminshall     do {
5832146Sminshall 	FD_ZERO(&excepts);
5932552Sminshall 	FD_SET(net, &excepts);
6032552Sminshall 	value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
6132146Sminshall     } while ((value == -1) && (errno == EINTR));
6232146Sminshall 
6332146Sminshall     if (value < 0) {
6432146Sminshall 	perror("select");
6534848Sminshall 	(void) quit();
6632146Sminshall     }
6732552Sminshall     if (FD_ISSET(net, &excepts)) {
6832146Sminshall 	return 1;
6932146Sminshall     } else {
7032146Sminshall 	return 0;
7132146Sminshall     }
7232146Sminshall }
7332146Sminshall 
7432146Sminshall 
7532146Sminshall /*
7632257Sminshall  *  setneturg()
7732257Sminshall  *
7832257Sminshall  *	Sets "neturg" to the current location.
7932257Sminshall  */
8032257Sminshall 
8132257Sminshall void
8232257Sminshall setneturg()
8332257Sminshall {
8432381Sminshall     ring_mark(&netoring);
8532257Sminshall }
8632257Sminshall 
8732257Sminshall 
8832257Sminshall /*
8932146Sminshall  *  netflush
9032146Sminshall  *		Send as much data as possible to the network,
9132146Sminshall  *	handling requests for urgent data.
9232146Sminshall  *
9332146Sminshall  *		The return value indicates whether we did any
9432146Sminshall  *	useful work.
9532146Sminshall  */
9632146Sminshall 
9732146Sminshall 
9832146Sminshall int
9932146Sminshall netflush()
10032146Sminshall {
10133294Sminshall     register int n, n1;
10232146Sminshall 
10332667Sminshall     if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
10432381Sminshall 	if (!ring_at_mark(&netoring)) {
10532528Sminshall 	    n = send(net, netoring.consume, n, 0);	/* normal write */
10632146Sminshall 	} else {
10732146Sminshall 	    /*
10832146Sminshall 	     * In 4.2 (and 4.3) systems, there is some question about
10932146Sminshall 	     * what byte in a sendOOB operation is the "OOB" data.
11032146Sminshall 	     * To make ourselves compatible, we only send ONE byte
11132146Sminshall 	     * out of band, the one WE THINK should be OOB (though
11232146Sminshall 	     * we really have more the TCP philosophy of urgent data
11332146Sminshall 	     * rather than the Unix philosophy of OOB data).
11432146Sminshall 	     */
11532528Sminshall 	    n = send(net, netoring.consume, 1, MSG_OOB);/* URGENT data */
11632146Sminshall 	}
11732146Sminshall     }
11832146Sminshall     if (n < 0) {
11932146Sminshall 	if (errno != ENOBUFS && errno != EWOULDBLOCK) {
12032146Sminshall 	    setcommandmode();
12132146Sminshall 	    perror(hostname);
12232146Sminshall 	    NetClose(net);
12332381Sminshall 	    ring_clear_mark(&netoring);
12432146Sminshall 	    longjmp(peerdied, -1);
12532146Sminshall 	    /*NOTREACHED*/
12632146Sminshall 	}
12732146Sminshall 	n = 0;
12832146Sminshall     }
12932146Sminshall     if (netdata && n) {
13032528Sminshall 	Dump('>', netoring.consume, n);
13132146Sminshall     }
13232667Sminshall     if (n) {
13333294Sminshall 	ring_consumed(&netoring, n);
13433294Sminshall 	/*
13533294Sminshall 	 * If we sent all, and more to send, then recurse to pick
13633294Sminshall 	 * up the other half.
13733294Sminshall 	 */
13833294Sminshall 	if ((n1 == n) && ring_full_consecutive(&netoring)) {
13933294Sminshall 	    (void) netflush();
14032667Sminshall 	}
14133294Sminshall 	return 1;
14233294Sminshall     } else {
14333294Sminshall 	return 0;
14432667Sminshall     }
14532146Sminshall }
146