133685Sbostic /* 233685Sbostic * Copyright (c) 1988 Regents of the University of California. 333685Sbostic * All rights reserved. 433685Sbostic * 5*42770Sbostic * %sccs.include.redist.c% 633685Sbostic */ 733685Sbostic 833685Sbostic #ifndef lint 9*42770Sbostic static char sccsid[] = "@(#)network.c 1.14 (Berkeley) 06/01/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(); 6632146Sminshall } 6732552Sminshall if (FD_ISSET(net, &excepts)) { 6832146Sminshall return 1; 6932146Sminshall } else { 7032146Sminshall return 0; 7132146Sminshall } 7232146Sminshall } 7332146Sminshall 7432146Sminshall 7532146Sminshall /* 7632257Sminshall * setneturg() 7732257Sminshall * 7832257Sminshall * Sets "neturg" to the current location. 7932257Sminshall */ 8032257Sminshall 8132257Sminshall void 8232257Sminshall setneturg() 8332257Sminshall { 8432381Sminshall ring_mark(&netoring); 8532257Sminshall } 8632257Sminshall 8732257Sminshall 8832257Sminshall /* 8932146Sminshall * netflush 9032146Sminshall * Send as much data as possible to the network, 9132146Sminshall * handling requests for urgent data. 9232146Sminshall * 9332146Sminshall * The return value indicates whether we did any 9432146Sminshall * useful work. 9532146Sminshall */ 9632146Sminshall 9732146Sminshall 9832146Sminshall int 9932146Sminshall netflush() 10032146Sminshall { 10133294Sminshall register int n, n1; 10232146Sminshall 10332667Sminshall if ((n1 = n = ring_full_consecutive(&netoring)) > 0) { 10432381Sminshall if (!ring_at_mark(&netoring)) { 10532528Sminshall n = send(net, netoring.consume, n, 0); /* normal write */ 10632146Sminshall } else { 10732146Sminshall /* 10832146Sminshall * In 4.2 (and 4.3) systems, there is some question about 10932146Sminshall * what byte in a sendOOB operation is the "OOB" data. 11032146Sminshall * To make ourselves compatible, we only send ONE byte 11132146Sminshall * out of band, the one WE THINK should be OOB (though 11232146Sminshall * we really have more the TCP philosophy of urgent data 11332146Sminshall * rather than the Unix philosophy of OOB data). 11432146Sminshall */ 11532528Sminshall n = send(net, netoring.consume, 1, MSG_OOB);/* URGENT data */ 11632146Sminshall } 11732146Sminshall } 11832146Sminshall if (n < 0) { 11932146Sminshall if (errno != ENOBUFS && errno != EWOULDBLOCK) { 12032146Sminshall setcommandmode(); 12132146Sminshall perror(hostname); 12232146Sminshall NetClose(net); 12332381Sminshall ring_clear_mark(&netoring); 12432146Sminshall longjmp(peerdied, -1); 12532146Sminshall /*NOTREACHED*/ 12632146Sminshall } 12732146Sminshall n = 0; 12832146Sminshall } 12932146Sminshall if (netdata && n) { 13032528Sminshall Dump('>', netoring.consume, n); 13132146Sminshall } 13232667Sminshall if (n) { 13333294Sminshall ring_consumed(&netoring, n); 13433294Sminshall /* 13533294Sminshall * If we sent all, and more to send, then recurse to pick 13633294Sminshall * up the other half. 13733294Sminshall */ 13833294Sminshall if ((n1 == n) && ring_full_consecutive(&netoring)) { 13933294Sminshall (void) netflush(); 14032667Sminshall } 14133294Sminshall return 1; 14233294Sminshall } else { 14333294Sminshall return 0; 14432667Sminshall } 14532146Sminshall } 146