1184610Salfred/*
2184610Salfred * Copyright (c) 1988, 1993
3184610Salfred *	The Regents of the University of California.  All rights reserved.
4184610Salfred *
5184610Salfred * Redistribution and use in source and binary forms, with or without
6184610Salfred * modification, are permitted provided that the following conditions
7184610Salfred * are met:
8184610Salfred * 1. Redistributions of source code must retain the above copyright
9184610Salfred *    notice, this list of conditions and the following disclaimer.
10184610Salfred * 2. Redistributions in binary form must reproduce the above copyright
11184610Salfred *    notice, this list of conditions and the following disclaimer in the
12184610Salfred *    documentation and/or other materials provided with the distribution.
13184610Salfred * 3. All advertising materials mentioning features or use of this software
14184610Salfred *    must display the following acknowledgement:
15184610Salfred *	This product includes software developed by the University of
16184610Salfred *	California, Berkeley and its contributors.
17184610Salfred * 4. Neither the name of the University nor the names of its contributors
18184610Salfred *    may be used to endorse or promote products derived from this software
19184610Salfred *    without specific prior written permission.
20184610Salfred *
21184610Salfred * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22184610Salfred * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23184610Salfred * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24184610Salfred * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25184610Salfred * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26188417Sthompsa * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27184610Salfred * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28184610Salfred * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29191746Sthompsa * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30191746Sthompsa * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31191746Sthompsa * SUCH DAMAGE.
32191746Sthompsa */
33191746Sthompsa
34194677Sthompsa#if 0
35191746Sthompsa#ifndef lint
36191746Sthompsastatic const char sccsid[] = "@(#)network.c	8.2 (Berkeley) 12/15/93";
37191746Sthompsa#endif
38191746Sthompsa#endif
39191746Sthompsa#include <sys/cdefs.h>
40191746Sthompsa__FBSDID("$FreeBSD$");
41191746Sthompsa
42191746Sthompsa#include <sys/types.h>
43191746Sthompsa#include <sys/socket.h>
44191746Sthompsa#include <sys/time.h>
45191746Sthompsa
46191746Sthompsa#include <errno.h>
47191746Sthompsa#include <stdlib.h>
48191746Sthompsa
49191746Sthompsa#include <arpa/telnet.h>
50191746Sthompsa#include <unistd.h>
51191746Sthompsa
52191746Sthompsa#include "ring.h"
53191746Sthompsa
54191746Sthompsa#include "defines.h"
55191746Sthompsa#include "externs.h"
56191746Sthompsa#include "fdset.h"
57191746Sthompsa
58191746SthompsaRing		netoring, netiring;
59191746Sthompsaunsigned char	netobuf[2*BUFSIZ], netibuf[BUFSIZ];
60191746Sthompsa
61191746Sthompsa/*
62191746Sthompsa * Initialize internal network data structures.
63191746Sthompsa */
64206358Srpaulo
65191746Sthompsavoid
66188942Sthompsainit_network(void)
67194677Sthompsa{
68194677Sthompsa    if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) {
69191746Sthompsa	exit(1);
70184610Salfred    }
71188942Sthompsa    if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) {
72188942Sthompsa	exit(1);
73184610Salfred    }
74207077Sthompsa    NetTrace = stdout;
75184610Salfred}
76184610Salfred
77227309Sed
78192502Sthompsa/*
79184610Salfred * Check to see if any out-of-band data exists on a socket (for
80188417Sthompsa * Telnet "synch" processing).
81188417Sthompsa */
82188417Sthompsa
83188417Sthompsaint
84188417Sthompsastilloob(void)
85188417Sthompsa{
86188417Sthompsa    static struct timeval timeout = { 0, 0 };
87188417Sthompsa    fd_set	excepts;
88188417Sthompsa    int value;
89188417Sthompsa
90188417Sthompsa    do {
91188417Sthompsa	FD_ZERO(&excepts);
92188417Sthompsa	FD_SET(net, &excepts);
93188417Sthompsa	value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
94188417Sthompsa    } while ((value == -1) && (errno == EINTR));
95188419Sthompsa
96188417Sthompsa    if (value < 0) {
97188417Sthompsa	perror("select");
98188417Sthompsa	(void) quit();
99188417Sthompsa	/* NOTREACHED */
100188417Sthompsa    }
101188417Sthompsa    if (FD_ISSET(net, &excepts)) {
102184610Salfred	return 1;
103184610Salfred    } else {
104188419Sthompsa	return 0;
105194228Sthompsa    }
106188419Sthompsa}
107188417Sthompsa
108184610Salfred
109184610Salfred/*
110184610Salfred *  setneturg()
111193045Sthompsa *
112193045Sthompsa *	Sets "neturg" to the current location.
113193045Sthompsa */
114193045Sthompsa
115184610Salfredvoid
116185948Sthompsasetneturg(void)
117228621Sbschmidt{
118228621Sbschmidt    ring_mark(&netoring);
119228621Sbschmidt}
120185948Sthompsa
121188417Sthompsa
122188419Sthompsa/*
123188419Sthompsa *  netflush
124188417Sthompsa *		Send as much data as possible to the network,
125188417Sthompsa *	handling requests for urgent data.
126188601Sthompsa *
127188417Sthompsa *		The return value indicates whether we did any
128188417Sthompsa *	useful work.
129188417Sthompsa */
130188417Sthompsa
131188417Sthompsaint
132188417Sthompsanetflush(void)
133188417Sthompsa{
134188417Sthompsa    int n, n1;
135188417Sthompsa
136188417Sthompsa#ifdef	ENCRYPTION
137188417Sthompsa    if (encrypt_output)
138188417Sthompsa	ring_encrypt(&netoring, encrypt_output);
139188417Sthompsa#endif	/* ENCRYPTION */
140188417Sthompsa    if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
141188417Sthompsa	if (!ring_at_mark(&netoring)) {
142188417Sthompsa	    n = send(net, (char *)netoring.consume, n, 0); /* normal write */
143188417Sthompsa	} else {
144188417Sthompsa	    /*
145188417Sthompsa	     * In 4.2 (and 4.3) systems, there is some question about
146188417Sthompsa	     * what byte in a sendOOB operation is the "OOB" data.
147188417Sthompsa	     * To make ourselves compatible, we only send ONE byte
148188417Sthompsa	     * out of band, the one WE THINK should be OOB (though
149192984Sthompsa	     * we really have more the TCP philosophy of urgent data
150193803Sweongyo	     * rather than the Unix philosophy of OOB data).
151185948Sthompsa	     */
152188417Sthompsa	    n = send(net, (char *)netoring.consume, 1, MSG_OOB);/* URGENT data */
153188417Sthompsa	}
154185948Sthompsa    }
155188417Sthompsa    if (n < 0) {
156191746Sthompsa	if (errno != ENOBUFS && errno != EWOULDBLOCK) {
157188417Sthompsa	    setcommandmode();
158191746Sthompsa	    perror(hostname);
159188417Sthompsa	    (void)NetClose(net);
160188417Sthompsa	    ring_clear_mark(&netoring);
161188417Sthompsa	    ExitString("Connection closed by foreign host.\n", 1);
162188417Sthompsa	    /*NOTREACHED*/
163188417Sthompsa	}
164188417Sthompsa	n = 0;
165188417Sthompsa    }
166188417Sthompsa    if (netdata && n) {
167188417Sthompsa	Dump('>', netoring.consume, n);
168188417Sthompsa    }
169188417Sthompsa    if (n) {
170188417Sthompsa	ring_consumed(&netoring, n);
171188417Sthompsa	/*
172188417Sthompsa	 * If we sent all, and more to send, then recurse to pick
173188417Sthompsa	 * up the other half.
174188417Sthompsa	 */
175188417Sthompsa	if ((n1 == n) && ring_full_consecutive(&netoring)) {
176188417Sthompsa	    (void) netflush();
177188417Sthompsa	}
178188417Sthompsa	return 1;
179188417Sthompsa    } else {
180193420Sweongyo	return 0;
181193420Sweongyo    }
182193420Sweongyo}
183193420Sweongyo