132146Sminshall #include <sys/types.h> 232146Sminshall #include <sys/socket.h> 332146Sminshall #include <sys/time.h> 432146Sminshall 532146Sminshall #include <errno.h> 632146Sminshall 732146Sminshall #include <arpa/telnet.h> 832146Sminshall 932381Sminshall #include "ring.h" 1032381Sminshall 1132146Sminshall #include "defines.h" 1232146Sminshall #include "externs.h" 1332146Sminshall 1432531Sminshall Ring netoring, netiring; 1532531Sminshall char netobuf[2*BUFSIZ], netibuf[BUFSIZ]; 1632146Sminshall 1732146Sminshall /* 1832146Sminshall * Initialize internal network data structures. 1932146Sminshall */ 2032146Sminshall 2132146Sminshall init_network() 2232146Sminshall { 2332381Sminshall ring_init(&netoring, netobuf, sizeof netobuf); 2432531Sminshall ring_init(&netiring, netibuf, sizeof netibuf); 2532146Sminshall NetTrace = stdout; 2632146Sminshall } 2732146Sminshall 2832146Sminshall 2932146Sminshall /* 3032146Sminshall * Check to see if any out-of-band data exists on a socket (for 3132146Sminshall * Telnet "synch" processing). 3232146Sminshall */ 3332146Sminshall 3432146Sminshall int 35*32552Sminshall stilloob() 3632146Sminshall { 3732146Sminshall static struct timeval timeout = { 0 }; 3832146Sminshall fd_set excepts; 3932146Sminshall int value; 4032146Sminshall 4132146Sminshall do { 4232146Sminshall FD_ZERO(&excepts); 43*32552Sminshall FD_SET(net, &excepts); 44*32552Sminshall value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout); 4532146Sminshall } while ((value == -1) && (errno == EINTR)); 4632146Sminshall 4732146Sminshall if (value < 0) { 4832146Sminshall perror("select"); 4932146Sminshall quit(); 5032146Sminshall } 51*32552Sminshall if (FD_ISSET(net, &excepts)) { 5232146Sminshall return 1; 5332146Sminshall } else { 5432146Sminshall return 0; 5532146Sminshall } 5632146Sminshall } 5732146Sminshall 5832146Sminshall 5932146Sminshall /* 6032257Sminshall * setneturg() 6132257Sminshall * 6232257Sminshall * Sets "neturg" to the current location. 6332257Sminshall */ 6432257Sminshall 6532257Sminshall void 6632257Sminshall setneturg() 6732257Sminshall { 6832381Sminshall ring_mark(&netoring); 6932257Sminshall } 7032257Sminshall 7132257Sminshall 7232257Sminshall /* 7332146Sminshall * netflush 7432146Sminshall * Send as much data as possible to the network, 7532146Sminshall * handling requests for urgent data. 7632146Sminshall * 7732146Sminshall * The return value indicates whether we did any 7832146Sminshall * useful work. 7932146Sminshall */ 8032146Sminshall 8132146Sminshall 8232146Sminshall int 8332146Sminshall netflush() 8432146Sminshall { 8532146Sminshall int n; 8632146Sminshall 8732528Sminshall if ((n = ring_full_consecutive(&netoring)) > 0) { 8832381Sminshall if (!ring_at_mark(&netoring)) { 8932528Sminshall n = send(net, netoring.consume, n, 0); /* normal write */ 9032146Sminshall } else { 9132146Sminshall /* 9232146Sminshall * In 4.2 (and 4.3) systems, there is some question about 9332146Sminshall * what byte in a sendOOB operation is the "OOB" data. 9432146Sminshall * To make ourselves compatible, we only send ONE byte 9532146Sminshall * out of band, the one WE THINK should be OOB (though 9632146Sminshall * we really have more the TCP philosophy of urgent data 9732146Sminshall * rather than the Unix philosophy of OOB data). 9832146Sminshall */ 9932528Sminshall n = send(net, netoring.consume, 1, MSG_OOB);/* URGENT data */ 10032146Sminshall } 10132146Sminshall } 10232146Sminshall if (n < 0) { 10332146Sminshall if (errno != ENOBUFS && errno != EWOULDBLOCK) { 10432146Sminshall setcommandmode(); 10532146Sminshall perror(hostname); 10632146Sminshall NetClose(net); 10732381Sminshall ring_clear_mark(&netoring); 10832146Sminshall longjmp(peerdied, -1); 10932146Sminshall /*NOTREACHED*/ 11032146Sminshall } 11132146Sminshall n = 0; 11232146Sminshall } 11332146Sminshall if (netdata && n) { 11432528Sminshall Dump('>', netoring.consume, n); 11532146Sminshall } 11632528Sminshall ring_consumed(&netoring, n); 11732146Sminshall return n > 0; 11832146Sminshall } 119