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