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" 1332667Sminshall #include "fdset.h" 1432146Sminshall 1532531Sminshall Ring netoring, netiring; 1632531Sminshall char netobuf[2*BUFSIZ], netibuf[BUFSIZ]; 1732146Sminshall 1832146Sminshall /* 1932146Sminshall * Initialize internal network data structures. 2032146Sminshall */ 2132146Sminshall 2232146Sminshall init_network() 2332146Sminshall { 2432381Sminshall ring_init(&netoring, netobuf, sizeof netobuf); 2532531Sminshall ring_init(&netiring, netibuf, sizeof netibuf); 2632146Sminshall NetTrace = stdout; 2732146Sminshall } 2832146Sminshall 2932146Sminshall 3032146Sminshall /* 3132146Sminshall * Check to see if any out-of-band data exists on a socket (for 3232146Sminshall * Telnet "synch" processing). 3332146Sminshall */ 3432146Sminshall 3532146Sminshall int 3632552Sminshall stilloob() 3732146Sminshall { 3832146Sminshall static struct timeval timeout = { 0 }; 3932146Sminshall fd_set excepts; 4032146Sminshall int value; 4132146Sminshall 4232146Sminshall do { 4332146Sminshall FD_ZERO(&excepts); 4432552Sminshall FD_SET(net, &excepts); 4532552Sminshall value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout); 4632146Sminshall } while ((value == -1) && (errno == EINTR)); 4732146Sminshall 4832146Sminshall if (value < 0) { 4932146Sminshall perror("select"); 5032146Sminshall quit(); 5132146Sminshall } 5232552Sminshall if (FD_ISSET(net, &excepts)) { 5332146Sminshall return 1; 5432146Sminshall } else { 5532146Sminshall return 0; 5632146Sminshall } 5732146Sminshall } 5832146Sminshall 5932146Sminshall 6032146Sminshall /* 6132257Sminshall * setneturg() 6232257Sminshall * 6332257Sminshall * Sets "neturg" to the current location. 6432257Sminshall */ 6532257Sminshall 6632257Sminshall void 6732257Sminshall setneturg() 6832257Sminshall { 6932381Sminshall ring_mark(&netoring); 7032257Sminshall } 7132257Sminshall 7232257Sminshall 7332257Sminshall /* 7432146Sminshall * netflush 7532146Sminshall * Send as much data as possible to the network, 7632146Sminshall * handling requests for urgent data. 7732146Sminshall * 7832146Sminshall * The return value indicates whether we did any 7932146Sminshall * useful work. 8032146Sminshall */ 8132146Sminshall 8232146Sminshall 8332146Sminshall int 8432146Sminshall netflush() 8532146Sminshall { 86*33294Sminshall register int n, n1; 8732146Sminshall 8832667Sminshall if ((n1 = n = ring_full_consecutive(&netoring)) > 0) { 8932381Sminshall if (!ring_at_mark(&netoring)) { 9032528Sminshall n = send(net, netoring.consume, n, 0); /* normal write */ 9132146Sminshall } else { 9232146Sminshall /* 9332146Sminshall * In 4.2 (and 4.3) systems, there is some question about 9432146Sminshall * what byte in a sendOOB operation is the "OOB" data. 9532146Sminshall * To make ourselves compatible, we only send ONE byte 9632146Sminshall * out of band, the one WE THINK should be OOB (though 9732146Sminshall * we really have more the TCP philosophy of urgent data 9832146Sminshall * rather than the Unix philosophy of OOB data). 9932146Sminshall */ 10032528Sminshall n = send(net, netoring.consume, 1, MSG_OOB);/* URGENT data */ 10132146Sminshall } 10232146Sminshall } 10332146Sminshall if (n < 0) { 10432146Sminshall if (errno != ENOBUFS && errno != EWOULDBLOCK) { 10532146Sminshall setcommandmode(); 10632146Sminshall perror(hostname); 10732146Sminshall NetClose(net); 10832381Sminshall ring_clear_mark(&netoring); 10932146Sminshall longjmp(peerdied, -1); 11032146Sminshall /*NOTREACHED*/ 11132146Sminshall } 11232146Sminshall n = 0; 11332146Sminshall } 11432146Sminshall if (netdata && n) { 11532528Sminshall Dump('>', netoring.consume, n); 11632146Sminshall } 11732667Sminshall if (n) { 118*33294Sminshall ring_consumed(&netoring, n); 119*33294Sminshall /* 120*33294Sminshall * If we sent all, and more to send, then recurse to pick 121*33294Sminshall * up the other half. 122*33294Sminshall */ 123*33294Sminshall if ((n1 == n) && ring_full_consecutive(&netoring)) { 124*33294Sminshall (void) netflush(); 12532667Sminshall } 126*33294Sminshall return 1; 127*33294Sminshall } else { 128*33294Sminshall return 0; 12932667Sminshall } 13032146Sminshall } 131