133685Sbostic /* 233685Sbostic * Copyright (c) 1988 Regents of the University of California. 333685Sbostic * All rights reserved. 433685Sbostic * 533685Sbostic * Redistribution and use in source and binary forms are permitted 633685Sbostic * provided that this notice is preserved and that due credit is given 733685Sbostic * to the University of California at Berkeley. The name of the University 833685Sbostic * may not be used to endorse or promote products derived from this 933685Sbostic * software without specific prior written permission. This software 1033685Sbostic * is provided ``as is'' without express or implied warranty. 1133685Sbostic */ 1233685Sbostic 1333685Sbostic #ifndef lint 14*34848Sminshall static char sccsid[] = "@(#)network.c 1.12 (Berkeley) 06/27/88"; 1533685Sbostic #endif /* not lint */ 1633685Sbostic 1732146Sminshall #include <sys/types.h> 1832146Sminshall #include <sys/socket.h> 1932146Sminshall #include <sys/time.h> 2032146Sminshall 2132146Sminshall #include <errno.h> 2232146Sminshall 2332146Sminshall #include <arpa/telnet.h> 2432146Sminshall 2532381Sminshall #include "ring.h" 2632381Sminshall 2732146Sminshall #include "defines.h" 2832146Sminshall #include "externs.h" 2932667Sminshall #include "fdset.h" 3032146Sminshall 3132531Sminshall Ring netoring, netiring; 3232531Sminshall char netobuf[2*BUFSIZ], netibuf[BUFSIZ]; 3332146Sminshall 3432146Sminshall /* 3532146Sminshall * Initialize internal network data structures. 3632146Sminshall */ 3732146Sminshall 3832146Sminshall init_network() 3932146Sminshall { 40*34848Sminshall if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) { 41*34848Sminshall exit(1); 42*34848Sminshall } 43*34848Sminshall if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) { 44*34848Sminshall exit(1); 45*34848Sminshall } 4632146Sminshall NetTrace = stdout; 4732146Sminshall } 4832146Sminshall 4932146Sminshall 5032146Sminshall /* 5132146Sminshall * Check to see if any out-of-band data exists on a socket (for 5232146Sminshall * Telnet "synch" processing). 5332146Sminshall */ 5432146Sminshall 5532146Sminshall int 5632552Sminshall stilloob() 5732146Sminshall { 5832146Sminshall static struct timeval timeout = { 0 }; 5932146Sminshall fd_set excepts; 6032146Sminshall int value; 6132146Sminshall 6232146Sminshall do { 6332146Sminshall FD_ZERO(&excepts); 6432552Sminshall FD_SET(net, &excepts); 6532552Sminshall value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout); 6632146Sminshall } while ((value == -1) && (errno == EINTR)); 6732146Sminshall 6832146Sminshall if (value < 0) { 6932146Sminshall perror("select"); 70*34848Sminshall (void) quit(); 7132146Sminshall } 7232552Sminshall if (FD_ISSET(net, &excepts)) { 7332146Sminshall return 1; 7432146Sminshall } else { 7532146Sminshall return 0; 7632146Sminshall } 7732146Sminshall } 7832146Sminshall 7932146Sminshall 8032146Sminshall /* 8132257Sminshall * setneturg() 8232257Sminshall * 8332257Sminshall * Sets "neturg" to the current location. 8432257Sminshall */ 8532257Sminshall 8632257Sminshall void 8732257Sminshall setneturg() 8832257Sminshall { 8932381Sminshall ring_mark(&netoring); 9032257Sminshall } 9132257Sminshall 9232257Sminshall 9332257Sminshall /* 9432146Sminshall * netflush 9532146Sminshall * Send as much data as possible to the network, 9632146Sminshall * handling requests for urgent data. 9732146Sminshall * 9832146Sminshall * The return value indicates whether we did any 9932146Sminshall * useful work. 10032146Sminshall */ 10132146Sminshall 10232146Sminshall 10332146Sminshall int 10432146Sminshall netflush() 10532146Sminshall { 10633294Sminshall register int n, n1; 10732146Sminshall 10832667Sminshall if ((n1 = n = ring_full_consecutive(&netoring)) > 0) { 10932381Sminshall if (!ring_at_mark(&netoring)) { 11032528Sminshall n = send(net, netoring.consume, n, 0); /* normal write */ 11132146Sminshall } else { 11232146Sminshall /* 11332146Sminshall * In 4.2 (and 4.3) systems, there is some question about 11432146Sminshall * what byte in a sendOOB operation is the "OOB" data. 11532146Sminshall * To make ourselves compatible, we only send ONE byte 11632146Sminshall * out of band, the one WE THINK should be OOB (though 11732146Sminshall * we really have more the TCP philosophy of urgent data 11832146Sminshall * rather than the Unix philosophy of OOB data). 11932146Sminshall */ 12032528Sminshall n = send(net, netoring.consume, 1, MSG_OOB);/* URGENT data */ 12132146Sminshall } 12232146Sminshall } 12332146Sminshall if (n < 0) { 12432146Sminshall if (errno != ENOBUFS && errno != EWOULDBLOCK) { 12532146Sminshall setcommandmode(); 12632146Sminshall perror(hostname); 12732146Sminshall NetClose(net); 12832381Sminshall ring_clear_mark(&netoring); 12932146Sminshall longjmp(peerdied, -1); 13032146Sminshall /*NOTREACHED*/ 13132146Sminshall } 13232146Sminshall n = 0; 13332146Sminshall } 13432146Sminshall if (netdata && n) { 13532528Sminshall Dump('>', netoring.consume, n); 13632146Sminshall } 13732667Sminshall if (n) { 13833294Sminshall ring_consumed(&netoring, n); 13933294Sminshall /* 14033294Sminshall * If we sent all, and more to send, then recurse to pick 14133294Sminshall * up the other half. 14233294Sminshall */ 14333294Sminshall if ((n1 == n) && ring_full_consecutive(&netoring)) { 14433294Sminshall (void) netflush(); 14532667Sminshall } 14633294Sminshall return 1; 14733294Sminshall } else { 14833294Sminshall return 0; 14932667Sminshall } 15032146Sminshall } 151