Home | History | Annotate | Line # | Download | only in telnet
      1 /*	$NetBSD: network.c,v 1.18 2018/12/14 23:40:17 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1988, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. Neither the name of the University nor the names of its contributors
     16  *    may be used to endorse or promote products derived from this software
     17  *    without specific prior written permission.
     18  *
     19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     29  * SUCH DAMAGE.
     30  */
     31 
     32 #include <sys/cdefs.h>
     33 #ifndef lint
     34 #if 0
     35 static char sccsid[] = "@(#)network.c	8.2 (Berkeley) 12/15/93";
     36 #else
     37 __RCSID("$NetBSD: network.c,v 1.18 2018/12/14 23:40:17 christos Exp $");
     38 #endif
     39 #endif /* not lint */
     40 
     41 #include <sys/types.h>
     42 #include <sys/socket.h>
     43 #include <sys/time.h>
     44 
     45 #include <errno.h>
     46 #include <unistd.h>
     47 #include <poll.h>
     48 
     49 #include <arpa/telnet.h>
     50 
     51 #include "ring.h"
     52 #include "defines.h"
     53 #include "externs.h"
     54 
     55 Ring		netoring, netiring;
     56 unsigned char	netobuf[2*BUFSIZ], netibuf[BUFSIZ];
     57 
     58 /*
     59  * Initialize internal network data structures.
     60  */
     61 
     62 void
     63 init_network(void)
     64 {
     65     if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) {
     66 	exit(1);
     67     }
     68     if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) {
     69 	exit(1);
     70     }
     71     NetTrace = stdout;
     72 }
     73 
     74 
     75 /*
     76  * Check to see if any out-of-band data exists on a socket (for
     77  * Telnet "synch" processing).
     78  */
     79 
     80 int
     81 stilloob(void)
     82 {
     83     struct pollfd set[1];
     84     int value;
     85 
     86     set[0].fd = net;
     87     set[0].events = POLLPRI;
     88     do {
     89 	value = poll(set, 1, 0);
     90     } while ((value == -1) && (errno == EINTR));
     91 
     92     if (value < 0) {
     93 	perror("poll");
     94 	(void) quit(0, NULL);
     95 	/* NOTREACHED */
     96     }
     97     if (set[0].revents & POLLPRI) {
     98 	return 1;
     99     } else {
    100 	return 0;
    101     }
    102 }
    103 
    104 
    105 /*
    106  *  setneturg()
    107  *
    108  *	Sets "neturg" to the current location.
    109  */
    110 
    111 void
    112 setneturg(void)
    113 {
    114     ring_mark(&netoring);
    115 }
    116 
    117 
    118 /*
    119  *  netflush
    120  *		Send as much data as possible to the network,
    121  *	handling requests for urgent data.
    122  *
    123  *		The return value indicates whether we did any
    124  *	useful work.
    125  */
    126 
    127 
    128 int
    129 netflush(void)
    130 {
    131     ssize_t n, n1;
    132 
    133 #ifdef	ENCRYPTION
    134     if (encrypt_output)
    135 	ring_encrypt(&netoring, encrypt_output);
    136 #endif	/* ENCRYPTION */
    137     if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
    138 	if (!ring_at_mark(&netoring)) {
    139 	    n = send(net, netoring.consume, (size_t)n, 0); /* normal write */
    140 	} else {
    141 	    /*
    142 	     * In 4.2 (and 4.3) systems, there is some question about
    143 	     * what byte in a sendOOB operation is the "OOB" data.
    144 	     * To make ourselves compatible, we only send ONE byte
    145 	     * out of band, the one WE THINK should be OOB (though
    146 	     * we really have more the TCP philosophy of urgent data
    147 	     * rather than the Unix philosophy of OOB data).
    148 	     */
    149 	    n = send(net, netoring.consume, 1, MSG_OOB);/* URGENT data */
    150 	}
    151     }
    152     if (n < 0) {
    153 	if (errno != ENOBUFS && errno != EWOULDBLOCK) {
    154 	    setcommandmode();
    155 	    perror(hostname);
    156 	    (void)NetClose(net);
    157 	    ring_clear_mark(&netoring);
    158 	    ExitString("Connection closed by foreign host.\n", 1);
    159 	    /*NOTREACHED*/
    160 	}
    161 	n = 0;
    162     }
    163     if (netdata && n) {
    164 	Dump('>', netoring.consume, (int)n);
    165     }
    166     if (n) {
    167 	ring_consumed(&netoring, (int)n);
    168 	/*
    169 	 * If we sent all, and more to send, then recurse to pick
    170 	 * up the other half.
    171 	 */
    172 	if ((n1 == n) && ring_full_consecutive(&netoring)) {
    173 	    (void) netflush();
    174 	}
    175 	return 1;
    176     } else {
    177 	return 0;
    178     }
    179 }
    180