xref: /csrg-svn/usr.bin/telnet/network.c (revision 34848)
133685Sbostic /*
233685Sbostic  * Copyright (c) 1988 Regents of the University of California.
333685Sbostic  * All rights reserved.
433685Sbostic  *
533685Sbostic  * Redistribution and use in source and binary forms are permitted
633685Sbostic  * provided that this notice is preserved and that due credit is given
733685Sbostic  * to the University of California at Berkeley. The name of the University
833685Sbostic  * may not be used to endorse or promote products derived from this
933685Sbostic  * software without specific prior written permission. This software
1033685Sbostic  * is provided ``as is'' without express or implied warranty.
1133685Sbostic  */
1233685Sbostic 
1333685Sbostic #ifndef lint
14*34848Sminshall static char sccsid[] = "@(#)network.c	1.12 (Berkeley) 06/27/88";
1533685Sbostic #endif /* not lint */
1633685Sbostic 
1732146Sminshall #include <sys/types.h>
1832146Sminshall #include <sys/socket.h>
1932146Sminshall #include <sys/time.h>
2032146Sminshall 
2132146Sminshall #include <errno.h>
2232146Sminshall 
2332146Sminshall #include <arpa/telnet.h>
2432146Sminshall 
2532381Sminshall #include "ring.h"
2632381Sminshall 
2732146Sminshall #include "defines.h"
2832146Sminshall #include "externs.h"
2932667Sminshall #include "fdset.h"
3032146Sminshall 
3132531Sminshall Ring	netoring, netiring;
3232531Sminshall char	netobuf[2*BUFSIZ], netibuf[BUFSIZ];
3332146Sminshall 
3432146Sminshall /*
3532146Sminshall  * Initialize internal network data structures.
3632146Sminshall  */
3732146Sminshall 
3832146Sminshall init_network()
3932146Sminshall {
40*34848Sminshall     if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) {
41*34848Sminshall 	exit(1);
42*34848Sminshall     }
43*34848Sminshall     if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) {
44*34848Sminshall 	exit(1);
45*34848Sminshall     }
4632146Sminshall     NetTrace = stdout;
4732146Sminshall }
4832146Sminshall 
4932146Sminshall 
5032146Sminshall /*
5132146Sminshall  * Check to see if any out-of-band data exists on a socket (for
5232146Sminshall  * Telnet "synch" processing).
5332146Sminshall  */
5432146Sminshall 
5532146Sminshall int
5632552Sminshall stilloob()
5732146Sminshall {
5832146Sminshall     static struct timeval timeout = { 0 };
5932146Sminshall     fd_set	excepts;
6032146Sminshall     int value;
6132146Sminshall 
6232146Sminshall     do {
6332146Sminshall 	FD_ZERO(&excepts);
6432552Sminshall 	FD_SET(net, &excepts);
6532552Sminshall 	value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
6632146Sminshall     } while ((value == -1) && (errno == EINTR));
6732146Sminshall 
6832146Sminshall     if (value < 0) {
6932146Sminshall 	perror("select");
70*34848Sminshall 	(void) quit();
7132146Sminshall     }
7232552Sminshall     if (FD_ISSET(net, &excepts)) {
7332146Sminshall 	return 1;
7432146Sminshall     } else {
7532146Sminshall 	return 0;
7632146Sminshall     }
7732146Sminshall }
7832146Sminshall 
7932146Sminshall 
8032146Sminshall /*
8132257Sminshall  *  setneturg()
8232257Sminshall  *
8332257Sminshall  *	Sets "neturg" to the current location.
8432257Sminshall  */
8532257Sminshall 
8632257Sminshall void
8732257Sminshall setneturg()
8832257Sminshall {
8932381Sminshall     ring_mark(&netoring);
9032257Sminshall }
9132257Sminshall 
9232257Sminshall 
9332257Sminshall /*
9432146Sminshall  *  netflush
9532146Sminshall  *		Send as much data as possible to the network,
9632146Sminshall  *	handling requests for urgent data.
9732146Sminshall  *
9832146Sminshall  *		The return value indicates whether we did any
9932146Sminshall  *	useful work.
10032146Sminshall  */
10132146Sminshall 
10232146Sminshall 
10332146Sminshall int
10432146Sminshall netflush()
10532146Sminshall {
10633294Sminshall     register int n, n1;
10732146Sminshall 
10832667Sminshall     if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
10932381Sminshall 	if (!ring_at_mark(&netoring)) {
11032528Sminshall 	    n = send(net, netoring.consume, n, 0);	/* normal write */
11132146Sminshall 	} else {
11232146Sminshall 	    /*
11332146Sminshall 	     * In 4.2 (and 4.3) systems, there is some question about
11432146Sminshall 	     * what byte in a sendOOB operation is the "OOB" data.
11532146Sminshall 	     * To make ourselves compatible, we only send ONE byte
11632146Sminshall 	     * out of band, the one WE THINK should be OOB (though
11732146Sminshall 	     * we really have more the TCP philosophy of urgent data
11832146Sminshall 	     * rather than the Unix philosophy of OOB data).
11932146Sminshall 	     */
12032528Sminshall 	    n = send(net, netoring.consume, 1, MSG_OOB);/* URGENT data */
12132146Sminshall 	}
12232146Sminshall     }
12332146Sminshall     if (n < 0) {
12432146Sminshall 	if (errno != ENOBUFS && errno != EWOULDBLOCK) {
12532146Sminshall 	    setcommandmode();
12632146Sminshall 	    perror(hostname);
12732146Sminshall 	    NetClose(net);
12832381Sminshall 	    ring_clear_mark(&netoring);
12932146Sminshall 	    longjmp(peerdied, -1);
13032146Sminshall 	    /*NOTREACHED*/
13132146Sminshall 	}
13232146Sminshall 	n = 0;
13332146Sminshall     }
13432146Sminshall     if (netdata && n) {
13532528Sminshall 	Dump('>', netoring.consume, n);
13632146Sminshall     }
13732667Sminshall     if (n) {
13833294Sminshall 	ring_consumed(&netoring, n);
13933294Sminshall 	/*
14033294Sminshall 	 * If we sent all, and more to send, then recurse to pick
14133294Sminshall 	 * up the other half.
14233294Sminshall 	 */
14333294Sminshall 	if ((n1 == n) && ring_full_consecutive(&netoring)) {
14433294Sminshall 	    (void) netflush();
14532667Sminshall 	}
14633294Sminshall 	return 1;
14733294Sminshall     } else {
14833294Sminshall 	return 0;
14932667Sminshall     }
15032146Sminshall }
151