133685Sbostic /* 2*62311Sbostic * Copyright (c) 1988, 1993 3*62311Sbostic * The Regents of the University of California. All rights reserved. 433685Sbostic * 542770Sbostic * %sccs.include.redist.c% 633685Sbostic */ 733685Sbostic 833685Sbostic #ifndef lint 9*62311Sbostic static char sccsid[] = "@(#)network.c 8.1 (Berkeley) 06/06/93"; 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 2646808Sdab Ring netoring, netiring; 2746808Sdab unsigned char netobuf[2*BUFSIZ], netibuf[BUFSIZ]; 2832146Sminshall 2932146Sminshall /* 3032146Sminshall * Initialize internal network data structures. 3132146Sminshall */ 3232146Sminshall 3346808Sdab void 3432146Sminshall init_network() 3532146Sminshall { 3634848Sminshall if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) { 3734848Sminshall exit(1); 3834848Sminshall } 3934848Sminshall if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) { 4034848Sminshall exit(1); 4134848Sminshall } 4232146Sminshall NetTrace = stdout; 4332146Sminshall } 4432146Sminshall 4532146Sminshall 4632146Sminshall /* 4732146Sminshall * Check to see if any out-of-band data exists on a socket (for 4832146Sminshall * Telnet "synch" processing). 4932146Sminshall */ 5032146Sminshall 5146808Sdab int 5232552Sminshall stilloob() 5332146Sminshall { 5432146Sminshall static struct timeval timeout = { 0 }; 5532146Sminshall fd_set excepts; 5632146Sminshall int value; 5732146Sminshall 5832146Sminshall do { 5932146Sminshall FD_ZERO(&excepts); 6032552Sminshall FD_SET(net, &excepts); 6132552Sminshall value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout); 6232146Sminshall } while ((value == -1) && (errno == EINTR)); 6332146Sminshall 6432146Sminshall if (value < 0) { 6532146Sminshall perror("select"); 6634848Sminshall (void) quit(); 6744360Sborman /* NOTREACHED */ 6832146Sminshall } 6932552Sminshall if (FD_ISSET(net, &excepts)) { 7032146Sminshall return 1; 7132146Sminshall } else { 7232146Sminshall return 0; 7332146Sminshall } 7432146Sminshall } 7532146Sminshall 7632146Sminshall 7732146Sminshall /* 7832257Sminshall * setneturg() 7932257Sminshall * 8032257Sminshall * Sets "neturg" to the current location. 8132257Sminshall */ 8232257Sminshall 8346808Sdab void 8432257Sminshall setneturg() 8532257Sminshall { 8632381Sminshall ring_mark(&netoring); 8732257Sminshall } 8832257Sminshall 8932257Sminshall 9032257Sminshall /* 9132146Sminshall * netflush 9232146Sminshall * Send as much data as possible to the network, 9332146Sminshall * handling requests for urgent data. 9432146Sminshall * 9532146Sminshall * The return value indicates whether we did any 9632146Sminshall * useful work. 9732146Sminshall */ 9832146Sminshall 9932146Sminshall 10046808Sdab int 10132146Sminshall netflush() 10232146Sminshall { 10333294Sminshall register int n, n1; 10432146Sminshall 10560149Sdab #ifdef ENCRYPTION 10646808Sdab if (encrypt_output) 10746808Sdab ring_encrypt(&netoring, encrypt_output); 10860149Sdab #endif /* ENCRYPTION */ 10932667Sminshall if ((n1 = n = ring_full_consecutive(&netoring)) > 0) { 11032381Sminshall if (!ring_at_mark(&netoring)) { 11132528Sminshall n = send(net, netoring.consume, n, 0); /* normal write */ 11232146Sminshall } else { 11332146Sminshall /* 11432146Sminshall * In 4.2 (and 4.3) systems, there is some question about 11532146Sminshall * what byte in a sendOOB operation is the "OOB" data. 11632146Sminshall * To make ourselves compatible, we only send ONE byte 11732146Sminshall * out of band, the one WE THINK should be OOB (though 11832146Sminshall * we really have more the TCP philosophy of urgent data 11932146Sminshall * rather than the Unix philosophy of OOB data). 12032146Sminshall */ 12132528Sminshall n = send(net, netoring.consume, 1, MSG_OOB);/* URGENT data */ 12232146Sminshall } 12332146Sminshall } 12432146Sminshall if (n < 0) { 12532146Sminshall if (errno != ENOBUFS && errno != EWOULDBLOCK) { 12632146Sminshall setcommandmode(); 12732146Sminshall perror(hostname); 12844360Sborman (void)NetClose(net); 12932381Sminshall ring_clear_mark(&netoring); 13032146Sminshall longjmp(peerdied, -1); 13132146Sminshall /*NOTREACHED*/ 13232146Sminshall } 13332146Sminshall n = 0; 13432146Sminshall } 13532146Sminshall if (netdata && n) { 13632528Sminshall Dump('>', netoring.consume, n); 13732146Sminshall } 13832667Sminshall if (n) { 13933294Sminshall ring_consumed(&netoring, n); 14033294Sminshall /* 14133294Sminshall * If we sent all, and more to send, then recurse to pick 14233294Sminshall * up the other half. 14333294Sminshall */ 14433294Sminshall if ((n1 == n) && ring_full_consecutive(&netoring)) { 14533294Sminshall (void) netflush(); 14632667Sminshall } 14733294Sminshall return 1; 14833294Sminshall } else { 14933294Sminshall return 0; 15032667Sminshall } 15132146Sminshall } 152