133685Sbostic /* 233685Sbostic * Copyright (c) 1988 Regents of the University of California. 333685Sbostic * All rights reserved. 433685Sbostic * 542770Sbostic * %sccs.include.redist.c% 633685Sbostic */ 733685Sbostic 833685Sbostic #ifndef lint 9*44360Sborman static char sccsid[] = "@(#)network.c 1.15 (Berkeley) 06/28/90"; 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 2632531Sminshall Ring netoring, netiring; 2732531Sminshall char netobuf[2*BUFSIZ], netibuf[BUFSIZ]; 2832146Sminshall 2932146Sminshall /* 3032146Sminshall * Initialize internal network data structures. 3132146Sminshall */ 3232146Sminshall 3332146Sminshall init_network() 3432146Sminshall { 3534848Sminshall if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) { 3634848Sminshall exit(1); 3734848Sminshall } 3834848Sminshall if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) { 3934848Sminshall exit(1); 4034848Sminshall } 4132146Sminshall NetTrace = stdout; 4232146Sminshall } 4332146Sminshall 4432146Sminshall 4532146Sminshall /* 4632146Sminshall * Check to see if any out-of-band data exists on a socket (for 4732146Sminshall * Telnet "synch" processing). 4832146Sminshall */ 4932146Sminshall 5032146Sminshall int 5132552Sminshall stilloob() 5232146Sminshall { 5332146Sminshall static struct timeval timeout = { 0 }; 5432146Sminshall fd_set excepts; 5532146Sminshall int value; 5632146Sminshall 5732146Sminshall do { 5832146Sminshall FD_ZERO(&excepts); 5932552Sminshall FD_SET(net, &excepts); 6032552Sminshall value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout); 6132146Sminshall } while ((value == -1) && (errno == EINTR)); 6232146Sminshall 6332146Sminshall if (value < 0) { 6432146Sminshall perror("select"); 6534848Sminshall (void) quit(); 66*44360Sborman /* NOTREACHED */ 6732146Sminshall } 6832552Sminshall if (FD_ISSET(net, &excepts)) { 6932146Sminshall return 1; 7032146Sminshall } else { 7132146Sminshall return 0; 7232146Sminshall } 7332146Sminshall } 7432146Sminshall 7532146Sminshall 7632146Sminshall /* 7732257Sminshall * setneturg() 7832257Sminshall * 7932257Sminshall * Sets "neturg" to the current location. 8032257Sminshall */ 8132257Sminshall 8232257Sminshall void 8332257Sminshall setneturg() 8432257Sminshall { 8532381Sminshall ring_mark(&netoring); 8632257Sminshall } 8732257Sminshall 8832257Sminshall 8932257Sminshall /* 9032146Sminshall * netflush 9132146Sminshall * Send as much data as possible to the network, 9232146Sminshall * handling requests for urgent data. 9332146Sminshall * 9432146Sminshall * The return value indicates whether we did any 9532146Sminshall * useful work. 9632146Sminshall */ 9732146Sminshall 9832146Sminshall 9932146Sminshall int 10032146Sminshall netflush() 10132146Sminshall { 10233294Sminshall register int n, n1; 10332146Sminshall 10432667Sminshall if ((n1 = n = ring_full_consecutive(&netoring)) > 0) { 10532381Sminshall if (!ring_at_mark(&netoring)) { 10632528Sminshall n = send(net, netoring.consume, n, 0); /* normal write */ 10732146Sminshall } else { 10832146Sminshall /* 10932146Sminshall * In 4.2 (and 4.3) systems, there is some question about 11032146Sminshall * what byte in a sendOOB operation is the "OOB" data. 11132146Sminshall * To make ourselves compatible, we only send ONE byte 11232146Sminshall * out of band, the one WE THINK should be OOB (though 11332146Sminshall * we really have more the TCP philosophy of urgent data 11432146Sminshall * rather than the Unix philosophy of OOB data). 11532146Sminshall */ 11632528Sminshall n = send(net, netoring.consume, 1, MSG_OOB);/* URGENT data */ 11732146Sminshall } 11832146Sminshall } 11932146Sminshall if (n < 0) { 12032146Sminshall if (errno != ENOBUFS && errno != EWOULDBLOCK) { 12132146Sminshall setcommandmode(); 12232146Sminshall perror(hostname); 123*44360Sborman (void)NetClose(net); 12432381Sminshall ring_clear_mark(&netoring); 12532146Sminshall longjmp(peerdied, -1); 12632146Sminshall /*NOTREACHED*/ 12732146Sminshall } 12832146Sminshall n = 0; 12932146Sminshall } 13032146Sminshall if (netdata && n) { 13132528Sminshall Dump('>', netoring.consume, n); 13232146Sminshall } 13332667Sminshall if (n) { 13433294Sminshall ring_consumed(&netoring, n); 13533294Sminshall /* 13633294Sminshall * If we sent all, and more to send, then recurse to pick 13733294Sminshall * up the other half. 13833294Sminshall */ 13933294Sminshall if ((n1 == n) && ring_full_consecutive(&netoring)) { 14033294Sminshall (void) netflush(); 14132667Sminshall } 14233294Sminshall return 1; 14333294Sminshall } else { 14433294Sminshall return 0; 14532667Sminshall } 14632146Sminshall } 147