/crypto/heimdal/appl/telnet/telnet/network.c

https://bitbucket.org/freebsd/freebsd-head/ · C · 173 lines · 87 code · 20 blank · 66 comment · 32 complexity · 5420c5fb5d7c575d078399461f495597 MD5 · raw file

  1. /*
  2. * Copyright (c) 1988, 1993
  3. * The Regents of the University of California. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. All advertising materials mentioning features or use of this software
  14. * must display the following acknowledgement:
  15. * This product includes software developed by the University of
  16. * California, Berkeley and its contributors.
  17. * 4. Neither the name of the University nor the names of its contributors
  18. * may be used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24. * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31. * SUCH DAMAGE.
  32. */
  33. #include "telnet_locl.h"
  34. RCSID("$Id$");
  35. Ring netoring, netiring;
  36. size_t netobufsize = 64*1024;
  37. size_t netibufsize = 64*1024;
  38. /*
  39. * Initialize internal network data structures.
  40. */
  41. void
  42. init_network(void)
  43. {
  44. void *obuf, *ibuf;
  45. if ((obuf = malloc(netobufsize)) == NULL)
  46. exit(1);
  47. if ((ibuf = malloc(netibufsize)) == NULL)
  48. exit(1);
  49. if (ring_init(&netoring, obuf, netobufsize) != 1) {
  50. exit(1);
  51. }
  52. if (ring_init(&netiring, ibuf, netibufsize) != 1) {
  53. exit(1);
  54. }
  55. NetTrace = stdout;
  56. }
  57. /*
  58. * Check to see if any out-of-band data exists on a socket (for
  59. * Telnet "synch" processing).
  60. */
  61. int
  62. stilloob(void)
  63. {
  64. static struct timeval timeout = { 0 };
  65. fd_set excepts;
  66. int value;
  67. do {
  68. FD_ZERO(&excepts);
  69. if (net >= FD_SETSIZE)
  70. errx (1, "fd too large");
  71. FD_SET(net, &excepts);
  72. value = select(net+1, 0, 0, &excepts, &timeout);
  73. } while ((value == -1) && (errno == EINTR));
  74. if (value < 0) {
  75. perror("select");
  76. quit();
  77. /* NOTREACHED */
  78. }
  79. if (FD_ISSET(net, &excepts)) {
  80. return 1;
  81. } else {
  82. return 0;
  83. }
  84. }
  85. /*
  86. * setneturg()
  87. *
  88. * Sets "neturg" to the current location.
  89. */
  90. void
  91. setneturg(void)
  92. {
  93. ring_mark(&netoring);
  94. }
  95. /*
  96. * netflush
  97. * Send as much data as possible to the network,
  98. * handling requests for urgent data.
  99. *
  100. * The return value indicates whether we did any
  101. * useful work.
  102. */
  103. int
  104. netflush(void)
  105. {
  106. int n, n1;
  107. #if defined(ENCRYPTION)
  108. if (encrypt_output)
  109. ring_encrypt(&netoring, encrypt_output);
  110. #endif
  111. if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
  112. if (!ring_at_mark(&netoring)) {
  113. n = send(net, (char *)netoring.consume, n, 0); /* normal write */
  114. } else {
  115. /*
  116. * In 4.2 (and 4.3) systems, there is some question about
  117. * what byte in a sendOOB operation is the "OOB" data.
  118. * To make ourselves compatible, we only send ONE byte
  119. * out of band, the one WE THINK should be OOB (though
  120. * we really have more the TCP philosophy of urgent data
  121. * rather than the Unix philosophy of OOB data).
  122. */
  123. n = send(net, (char *)netoring.consume, 1, MSG_OOB);/* URGENT data */
  124. }
  125. }
  126. if (n < 0) {
  127. if (errno != ENOBUFS && errno != EWOULDBLOCK) {
  128. setcommandmode();
  129. perror(hostname);
  130. NetClose(net);
  131. ring_clear_mark(&netoring);
  132. longjmp(peerdied, -1);
  133. /*NOTREACHED*/
  134. }
  135. n = 0;
  136. }
  137. if (netdata && n) {
  138. Dump('>', netoring.consume, n);
  139. }
  140. if (n) {
  141. ring_consumed(&netoring, n);
  142. /*
  143. * If we sent all, and more to send, then recurse to pick
  144. * up the other half.
  145. */
  146. if ((n1 == n) && ring_full_consecutive(&netoring)) {
  147. netflush();
  148. }
  149. return 1;
  150. } else {
  151. return 0;
  152. }
  153. }