xref: /csrg-svn/usr.bin/telnet/network.c (revision 33294)
132146Sminshall #include <sys/types.h>
232146Sminshall #include <sys/socket.h>
332146Sminshall #include <sys/time.h>
432146Sminshall 
532146Sminshall #include <errno.h>
632146Sminshall 
732146Sminshall #include <arpa/telnet.h>
832146Sminshall 
932381Sminshall #include "ring.h"
1032381Sminshall 
1132146Sminshall #include "defines.h"
1232146Sminshall #include "externs.h"
1332667Sminshall #include "fdset.h"
1432146Sminshall 
1532531Sminshall Ring	netoring, netiring;
1632531Sminshall char	netobuf[2*BUFSIZ], netibuf[BUFSIZ];
1732146Sminshall 
1832146Sminshall /*
1932146Sminshall  * Initialize internal network data structures.
2032146Sminshall  */
2132146Sminshall 
2232146Sminshall init_network()
2332146Sminshall {
2432381Sminshall     ring_init(&netoring, netobuf, sizeof netobuf);
2532531Sminshall     ring_init(&netiring, netibuf, sizeof netibuf);
2632146Sminshall     NetTrace = stdout;
2732146Sminshall }
2832146Sminshall 
2932146Sminshall 
3032146Sminshall /*
3132146Sminshall  * Check to see if any out-of-band data exists on a socket (for
3232146Sminshall  * Telnet "synch" processing).
3332146Sminshall  */
3432146Sminshall 
3532146Sminshall int
3632552Sminshall stilloob()
3732146Sminshall {
3832146Sminshall     static struct timeval timeout = { 0 };
3932146Sminshall     fd_set	excepts;
4032146Sminshall     int value;
4132146Sminshall 
4232146Sminshall     do {
4332146Sminshall 	FD_ZERO(&excepts);
4432552Sminshall 	FD_SET(net, &excepts);
4532552Sminshall 	value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
4632146Sminshall     } while ((value == -1) && (errno == EINTR));
4732146Sminshall 
4832146Sminshall     if (value < 0) {
4932146Sminshall 	perror("select");
5032146Sminshall 	quit();
5132146Sminshall     }
5232552Sminshall     if (FD_ISSET(net, &excepts)) {
5332146Sminshall 	return 1;
5432146Sminshall     } else {
5532146Sminshall 	return 0;
5632146Sminshall     }
5732146Sminshall }
5832146Sminshall 
5932146Sminshall 
6032146Sminshall /*
6132257Sminshall  *  setneturg()
6232257Sminshall  *
6332257Sminshall  *	Sets "neturg" to the current location.
6432257Sminshall  */
6532257Sminshall 
6632257Sminshall void
6732257Sminshall setneturg()
6832257Sminshall {
6932381Sminshall     ring_mark(&netoring);
7032257Sminshall }
7132257Sminshall 
7232257Sminshall 
7332257Sminshall /*
7432146Sminshall  *  netflush
7532146Sminshall  *		Send as much data as possible to the network,
7632146Sminshall  *	handling requests for urgent data.
7732146Sminshall  *
7832146Sminshall  *		The return value indicates whether we did any
7932146Sminshall  *	useful work.
8032146Sminshall  */
8132146Sminshall 
8232146Sminshall 
8332146Sminshall int
8432146Sminshall netflush()
8532146Sminshall {
86*33294Sminshall     register int n, n1;
8732146Sminshall 
8832667Sminshall     if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
8932381Sminshall 	if (!ring_at_mark(&netoring)) {
9032528Sminshall 	    n = send(net, netoring.consume, n, 0);	/* normal write */
9132146Sminshall 	} else {
9232146Sminshall 	    /*
9332146Sminshall 	     * In 4.2 (and 4.3) systems, there is some question about
9432146Sminshall 	     * what byte in a sendOOB operation is the "OOB" data.
9532146Sminshall 	     * To make ourselves compatible, we only send ONE byte
9632146Sminshall 	     * out of band, the one WE THINK should be OOB (though
9732146Sminshall 	     * we really have more the TCP philosophy of urgent data
9832146Sminshall 	     * rather than the Unix philosophy of OOB data).
9932146Sminshall 	     */
10032528Sminshall 	    n = send(net, netoring.consume, 1, MSG_OOB);/* URGENT data */
10132146Sminshall 	}
10232146Sminshall     }
10332146Sminshall     if (n < 0) {
10432146Sminshall 	if (errno != ENOBUFS && errno != EWOULDBLOCK) {
10532146Sminshall 	    setcommandmode();
10632146Sminshall 	    perror(hostname);
10732146Sminshall 	    NetClose(net);
10832381Sminshall 	    ring_clear_mark(&netoring);
10932146Sminshall 	    longjmp(peerdied, -1);
11032146Sminshall 	    /*NOTREACHED*/
11132146Sminshall 	}
11232146Sminshall 	n = 0;
11332146Sminshall     }
11432146Sminshall     if (netdata && n) {
11532528Sminshall 	Dump('>', netoring.consume, n);
11632146Sminshall     }
11732667Sminshall     if (n) {
118*33294Sminshall 	ring_consumed(&netoring, n);
119*33294Sminshall 	/*
120*33294Sminshall 	 * If we sent all, and more to send, then recurse to pick
121*33294Sminshall 	 * up the other half.
122*33294Sminshall 	 */
123*33294Sminshall 	if ((n1 == n) && ring_full_consecutive(&netoring)) {
124*33294Sminshall 	    (void) netflush();
12532667Sminshall 	}
126*33294Sminshall 	return 1;
127*33294Sminshall     } else {
128*33294Sminshall 	return 0;
12932667Sminshall     }
13032146Sminshall }
131