Flush out the last dregs in the terminal before quitting when
[unix-history] / usr / src / usr.bin / telnet / network.c
CommitLineData
897ce52e
KB
1/*
2 * Copyright (c) 1988 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms are permitted
b36fc510
KB
6 * provided that the above copyright notice and this paragraph are
7 * duplicated in all such forms and that any documentation,
8 * advertising materials, and other materials related to such
9 * distribution and use acknowledge that the software was developed
10 * by the University of California, Berkeley. The name of the
11 * University may not be used to endorse or promote products derived
12 * from this software without specific prior written permission.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
897ce52e
KB
16 */
17
18#ifndef lint
b36fc510 19static char sccsid[] = "@(#)network.c 1.13 (Berkeley) %G%";
897ce52e
KB
20#endif /* not lint */
21
8bca9c52
GM
22#include <sys/types.h>
23#include <sys/socket.h>
24#include <sys/time.h>
25
26#include <errno.h>
27
28#include <arpa/telnet.h>
29
115a5494
GM
30#include "ring.h"
31
8bca9c52
GM
32#include "defines.h"
33#include "externs.h"
ad1c581e 34#include "fdset.h"
8bca9c52 35
b307f09e
GM
36Ring netoring, netiring;
37char netobuf[2*BUFSIZ], netibuf[BUFSIZ];
8bca9c52
GM
38
39/*
40 * Initialize internal network data structures.
41 */
42
43init_network()
44{
80a47e22
GM
45 if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) {
46 exit(1);
47 }
48 if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) {
49 exit(1);
50 }
8bca9c52
GM
51 NetTrace = stdout;
52}
53
54
55/*
56 * Check to see if any out-of-band data exists on a socket (for
57 * Telnet "synch" processing).
58 */
59
60int
ddfe1126 61stilloob()
8bca9c52
GM
62{
63 static struct timeval timeout = { 0 };
64 fd_set excepts;
65 int value;
66
67 do {
68 FD_ZERO(&excepts);
ddfe1126
GM
69 FD_SET(net, &excepts);
70 value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
8bca9c52
GM
71 } while ((value == -1) && (errno == EINTR));
72
73 if (value < 0) {
74 perror("select");
80a47e22 75 (void) quit();
8bca9c52 76 }
ddfe1126 77 if (FD_ISSET(net, &excepts)) {
8bca9c52
GM
78 return 1;
79 } else {
80 return 0;
81 }
82}
83
84
d732be39
GM
85/*
86 * setneturg()
87 *
88 * Sets "neturg" to the current location.
89 */
90
91void
92setneturg()
93{
115a5494 94 ring_mark(&netoring);
d732be39
GM
95}
96
97
8bca9c52
GM
98/*
99 * netflush
100 * Send as much data as possible to the network,
101 * handling requests for urgent data.
102 *
103 * The return value indicates whether we did any
104 * useful work.
105 */
106
107
108int
109netflush()
110{
218b1a4c 111 register int n, n1;
8bca9c52 112
ad1c581e 113 if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
115a5494 114 if (!ring_at_mark(&netoring)) {
8b6750f5 115 n = send(net, netoring.consume, n, 0); /* normal write */
8bca9c52 116 } else {
8bca9c52
GM
117 /*
118 * In 4.2 (and 4.3) systems, there is some question about
119 * what byte in a sendOOB operation is the "OOB" data.
120 * To make ourselves compatible, we only send ONE byte
121 * out of band, the one WE THINK should be OOB (though
122 * we really have more the TCP philosophy of urgent data
123 * rather than the Unix philosophy of OOB data).
124 */
8b6750f5 125 n = send(net, netoring.consume, 1, MSG_OOB);/* URGENT data */
8bca9c52
GM
126 }
127 }
128 if (n < 0) {
129 if (errno != ENOBUFS && errno != EWOULDBLOCK) {
130 setcommandmode();
131 perror(hostname);
132 NetClose(net);
115a5494 133 ring_clear_mark(&netoring);
8bca9c52
GM
134 longjmp(peerdied, -1);
135 /*NOTREACHED*/
136 }
137 n = 0;
138 }
139 if (netdata && n) {
8b6750f5 140 Dump('>', netoring.consume, n);
8bca9c52 141 }
ad1c581e 142 if (n) {
ad1c581e 143 ring_consumed(&netoring, n);
218b1a4c
GM
144 /*
145 * If we sent all, and more to send, then recurse to pick
146 * up the other half.
147 */
148 if ((n1 == n) && ring_full_consecutive(&netoring)) {
149 (void) netflush();
150 }
151 return 1;
152 } else {
153 return 0;
ad1c581e 154 }
8bca9c52 155}