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