xref: /csrg-svn/usr.bin/telnet/network.c (revision 32552)
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"
1332146Sminshall 
1432531Sminshall Ring	netoring, netiring;
1532531Sminshall char	netobuf[2*BUFSIZ], netibuf[BUFSIZ];
1632146Sminshall 
1732146Sminshall /*
1832146Sminshall  * Initialize internal network data structures.
1932146Sminshall  */
2032146Sminshall 
2132146Sminshall init_network()
2232146Sminshall {
2332381Sminshall     ring_init(&netoring, netobuf, sizeof netobuf);
2432531Sminshall     ring_init(&netiring, netibuf, sizeof netibuf);
2532146Sminshall     NetTrace = stdout;
2632146Sminshall }
2732146Sminshall 
2832146Sminshall 
2932146Sminshall /*
3032146Sminshall  * Check to see if any out-of-band data exists on a socket (for
3132146Sminshall  * Telnet "synch" processing).
3232146Sminshall  */
3332146Sminshall 
3432146Sminshall int
35*32552Sminshall stilloob()
3632146Sminshall {
3732146Sminshall     static struct timeval timeout = { 0 };
3832146Sminshall     fd_set	excepts;
3932146Sminshall     int value;
4032146Sminshall 
4132146Sminshall     do {
4232146Sminshall 	FD_ZERO(&excepts);
43*32552Sminshall 	FD_SET(net, &excepts);
44*32552Sminshall 	value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
4532146Sminshall     } while ((value == -1) && (errno == EINTR));
4632146Sminshall 
4732146Sminshall     if (value < 0) {
4832146Sminshall 	perror("select");
4932146Sminshall 	quit();
5032146Sminshall     }
51*32552Sminshall     if (FD_ISSET(net, &excepts)) {
5232146Sminshall 	return 1;
5332146Sminshall     } else {
5432146Sminshall 	return 0;
5532146Sminshall     }
5632146Sminshall }
5732146Sminshall 
5832146Sminshall 
5932146Sminshall /*
6032257Sminshall  *  setneturg()
6132257Sminshall  *
6232257Sminshall  *	Sets "neturg" to the current location.
6332257Sminshall  */
6432257Sminshall 
6532257Sminshall void
6632257Sminshall setneturg()
6732257Sminshall {
6832381Sminshall     ring_mark(&netoring);
6932257Sminshall }
7032257Sminshall 
7132257Sminshall 
7232257Sminshall /*
7332146Sminshall  *  netflush
7432146Sminshall  *		Send as much data as possible to the network,
7532146Sminshall  *	handling requests for urgent data.
7632146Sminshall  *
7732146Sminshall  *		The return value indicates whether we did any
7832146Sminshall  *	useful work.
7932146Sminshall  */
8032146Sminshall 
8132146Sminshall 
8232146Sminshall int
8332146Sminshall netflush()
8432146Sminshall {
8532146Sminshall     int n;
8632146Sminshall 
8732528Sminshall     if ((n = ring_full_consecutive(&netoring)) > 0) {
8832381Sminshall 	if (!ring_at_mark(&netoring)) {
8932528Sminshall 	    n = send(net, netoring.consume, n, 0);	/* normal write */
9032146Sminshall 	} else {
9132146Sminshall 	    /*
9232146Sminshall 	     * In 4.2 (and 4.3) systems, there is some question about
9332146Sminshall 	     * what byte in a sendOOB operation is the "OOB" data.
9432146Sminshall 	     * To make ourselves compatible, we only send ONE byte
9532146Sminshall 	     * out of band, the one WE THINK should be OOB (though
9632146Sminshall 	     * we really have more the TCP philosophy of urgent data
9732146Sminshall 	     * rather than the Unix philosophy of OOB data).
9832146Sminshall 	     */
9932528Sminshall 	    n = send(net, netoring.consume, 1, MSG_OOB);/* URGENT data */
10032146Sminshall 	}
10132146Sminshall     }
10232146Sminshall     if (n < 0) {
10332146Sminshall 	if (errno != ENOBUFS && errno != EWOULDBLOCK) {
10432146Sminshall 	    setcommandmode();
10532146Sminshall 	    perror(hostname);
10632146Sminshall 	    NetClose(net);
10732381Sminshall 	    ring_clear_mark(&netoring);
10832146Sminshall 	    longjmp(peerdied, -1);
10932146Sminshall 	    /*NOTREACHED*/
11032146Sminshall 	}
11132146Sminshall 	n = 0;
11232146Sminshall     }
11332146Sminshall     if (netdata && n) {
11432528Sminshall 	Dump('>', netoring.consume, n);
11532146Sminshall     }
11632528Sminshall     ring_consumed(&netoring, n);
11732146Sminshall     return n > 0;
11832146Sminshall }
119