|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that this notice is preserved and that due credit is given ! 7: * to the University of California at Berkeley. The name of the University ! 8: * may not be used to endorse or promote products derived from this ! 9: * software without specific prior written permission. This software ! 10: * is provided ``as is'' without express or implied warranty. ! 11: */ ! 12: ! 13: #ifndef lint ! 14: static char sccsid[] = "@(#)network.c 1.11 (Berkeley) 3/8/88"; ! 15: #endif /* not lint */ ! 16: ! 17: #include <sys/types.h> ! 18: #include <sys/socket.h> ! 19: #include <sys/time.h> ! 20: ! 21: #include <errno.h> ! 22: ! 23: #include <arpa/telnet.h> ! 24: ! 25: #include "ring.h" ! 26: ! 27: #include "defines.h" ! 28: #include "externs.h" ! 29: #include "fdset.h" ! 30: ! 31: Ring netoring, netiring; ! 32: char netobuf[2*BUFSIZ], netibuf[BUFSIZ]; ! 33: ! 34: /* ! 35: * Initialize internal network data structures. ! 36: */ ! 37: ! 38: init_network() ! 39: { ! 40: ring_init(&netoring, netobuf, sizeof netobuf); ! 41: ring_init(&netiring, netibuf, sizeof netibuf); ! 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: quit(); ! 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: 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.