1 /* 2 * Copyright (c) 1988 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)network.c 1.15 (Berkeley) 06/28/90"; 10 #endif /* not lint */ 11 12 #include <sys/types.h> 13 #include <sys/socket.h> 14 #include <sys/time.h> 15 16 #include <errno.h> 17 18 #include <arpa/telnet.h> 19 20 #include "ring.h" 21 22 #include "defines.h" 23 #include "externs.h" 24 #include "fdset.h" 25 26 Ring netoring, netiring; 27 char netobuf[2*BUFSIZ], netibuf[BUFSIZ]; 28 29 /* 30 * Initialize internal network data structures. 31 */ 32 33 init_network() 34 { 35 if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) { 36 exit(1); 37 } 38 if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) { 39 exit(1); 40 } 41 NetTrace = stdout; 42 } 43 44 45 /* 46 * Check to see if any out-of-band data exists on a socket (for 47 * Telnet "synch" processing). 48 */ 49 50 int 51 stilloob() 52 { 53 static struct timeval timeout = { 0 }; 54 fd_set excepts; 55 int value; 56 57 do { 58 FD_ZERO(&excepts); 59 FD_SET(net, &excepts); 60 value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout); 61 } while ((value == -1) && (errno == EINTR)); 62 63 if (value < 0) { 64 perror("select"); 65 (void) quit(); 66 /* NOTREACHED */ 67 } 68 if (FD_ISSET(net, &excepts)) { 69 return 1; 70 } else { 71 return 0; 72 } 73 } 74 75 76 /* 77 * setneturg() 78 * 79 * Sets "neturg" to the current location. 80 */ 81 82 void 83 setneturg() 84 { 85 ring_mark(&netoring); 86 } 87 88 89 /* 90 * netflush 91 * Send as much data as possible to the network, 92 * handling requests for urgent data. 93 * 94 * The return value indicates whether we did any 95 * useful work. 96 */ 97 98 99 int 100 netflush() 101 { 102 register int n, n1; 103 104 if ((n1 = n = ring_full_consecutive(&netoring)) > 0) { 105 if (!ring_at_mark(&netoring)) { 106 n = send(net, netoring.consume, n, 0); /* normal write */ 107 } else { 108 /* 109 * In 4.2 (and 4.3) systems, there is some question about 110 * what byte in a sendOOB operation is the "OOB" data. 111 * To make ourselves compatible, we only send ONE byte 112 * out of band, the one WE THINK should be OOB (though 113 * we really have more the TCP philosophy of urgent data 114 * rather than the Unix philosophy of OOB data). 115 */ 116 n = send(net, netoring.consume, 1, MSG_OOB);/* URGENT data */ 117 } 118 } 119 if (n < 0) { 120 if (errno != ENOBUFS && errno != EWOULDBLOCK) { 121 setcommandmode(); 122 perror(hostname); 123 (void)NetClose(net); 124 ring_clear_mark(&netoring); 125 longjmp(peerdied, -1); 126 /*NOTREACHED*/ 127 } 128 n = 0; 129 } 130 if (netdata && n) { 131 Dump('>', netoring.consume, n); 132 } 133 if (n) { 134 ring_consumed(&netoring, n); 135 /* 136 * If we sent all, and more to send, then recurse to pick 137 * up the other half. 138 */ 139 if ((n1 == n) && ring_full_consecutive(&netoring)) { 140 (void) netflush(); 141 } 142 return 1; 143 } else { 144 return 0; 145 } 146 } 147