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.14 (Berkeley) 06/01/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 } 67 if (FD_ISSET(net, &excepts)) { 68 return 1; 69 } else { 70 return 0; 71 } 72 } 73 74 75 /* 76 * setneturg() 77 * 78 * Sets "neturg" to the current location. 79 */ 80 81 void 82 setneturg() 83 { 84 ring_mark(&netoring); 85 } 86 87 88 /* 89 * netflush 90 * Send as much data as possible to the network, 91 * handling requests for urgent data. 92 * 93 * The return value indicates whether we did any 94 * useful work. 95 */ 96 97 98 int 99 netflush() 100 { 101 register int n, n1; 102 103 if ((n1 = n = ring_full_consecutive(&netoring)) > 0) { 104 if (!ring_at_mark(&netoring)) { 105 n = send(net, netoring.consume, n, 0); /* normal write */ 106 } else { 107 /* 108 * In 4.2 (and 4.3) systems, there is some question about 109 * what byte in a sendOOB operation is the "OOB" data. 110 * To make ourselves compatible, we only send ONE byte 111 * out of band, the one WE THINK should be OOB (though 112 * we really have more the TCP philosophy of urgent data 113 * rather than the Unix philosophy of OOB data). 114 */ 115 n = send(net, netoring.consume, 1, MSG_OOB);/* URGENT data */ 116 } 117 } 118 if (n < 0) { 119 if (errno != ENOBUFS && errno != EWOULDBLOCK) { 120 setcommandmode(); 121 perror(hostname); 122 NetClose(net); 123 ring_clear_mark(&netoring); 124 longjmp(peerdied, -1); 125 /*NOTREACHED*/ 126 } 127 n = 0; 128 } 129 if (netdata && n) { 130 Dump('>', netoring.consume, n); 131 } 132 if (n) { 133 ring_consumed(&netoring, n); 134 /* 135 * If we sent all, and more to send, then recurse to pick 136 * up the other half. 137 */ 138 if ((n1 == n) && ring_full_consecutive(&netoring)) { 139 (void) netflush(); 140 } 141 return 1; 142 } else { 143 return 0; 144 } 145 } 146