+/*
+ * Copyright (c) 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static char sccsid[] = "@(#)network.c 1.13 (Berkeley) %G%";
+#endif /* not lint */
+
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include "defines.h"
#include "externs.h"
+#include "fdset.h"
-Ring netoring;
-char netobuf[2*BUFSIZ];
+Ring netoring, netiring;
+char netobuf[2*BUFSIZ], netibuf[BUFSIZ];
/*
* Initialize internal network data structures.
init_network()
{
- ring_init(&netoring, netobuf, sizeof netobuf);
+ if (ring_init(&netoring, netobuf, sizeof netobuf) != 1) {
+ exit(1);
+ }
+ if (ring_init(&netiring, netibuf, sizeof netibuf) != 1) {
+ exit(1);
+ }
NetTrace = stdout;
}
*/
int
-stilloob(s)
-int s; /* socket number */
+stilloob()
{
static struct timeval timeout = { 0 };
fd_set excepts;
do {
FD_ZERO(&excepts);
- FD_SET(s, &excepts);
- value = select(s+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
+ FD_SET(net, &excepts);
+ value = select(net+1, (fd_set *)0, (fd_set *)0, &excepts, &timeout);
} while ((value == -1) && (errno == EINTR));
if (value < 0) {
perror("select");
- quit();
+ (void) quit();
}
- if (FD_ISSET(s, &excepts)) {
+ if (FD_ISSET(net, &excepts)) {
return 1;
} else {
return 0;
int
netflush()
{
- int n;
+ register int n, n1;
- if ((n = ring_full_consecutive(&netoring)) > 0) {
+ if ((n1 = n = ring_full_consecutive(&netoring)) > 0) {
if (!ring_at_mark(&netoring)) {
n = send(net, netoring.consume, n, 0); /* normal write */
} else {
if (netdata && n) {
Dump('>', netoring.consume, n);
}
- ring_consumed(&netoring, n);
- return n > 0;
-}
-\f
-/*
- * nextitem()
- *
- * Return the address of the next "item" in the TELNET data
- * stream. This will be the address of the next character if
- * the current address is a user data character, or it will
- * be the address of the character following the TELNET command
- * if the current address is a TELNET IAC ("I Am a Command")
- * character.
- */
-
-static char *
-nextitem(current)
-char *current;
-{
- if ((*current&0xff) != IAC) {
- return current+1;
- }
- switch (*(current+1)&0xff) {
- case DO:
- case DONT:
- case WILL:
- case WONT:
- return current+3;
- case SB: /* loop forever looking for the SE */
- {
- register char *look = current+2;
-
- for (;;) {
- if ((*look++&0xff) == IAC) {
- if ((*look++&0xff) == SE) {
- return look;
- }
- }
- }
- }
- default:
- return current+2;
- }
-}
-
-/*
- * netclear()
- *
- * We are about to do a TELNET SYNCH operation. Clear
- * the path to the network.
- *
- * Things are a bit tricky since we may have sent the first
- * byte or so of a previous TELNET command into the network.
- * So, we have to scan the network buffer from the beginning
- * until we are up to where we want to be.
- *
- * A side effect of what we do, just to keep things
- * simple, is to clear the urgent data pointer. The principal
- * caller should be setting the urgent data pointer AFTER calling
- * us in any case.
- */
-
-void
-netclear()
-{
-#if 0 /* XXX */
- register char *thisitem, *next;
- char *good;
-#define wewant(p) ((nfrontp > p) && ((*p&0xff) == IAC) && \
- ((*(p+1)&0xff) != EC) && ((*(p+1)&0xff) != EL))
-
- thisitem = netobuf;
-
- while ((next = nextitem(thisitem)) <= netobuf.send) {
- thisitem = next;
- }
-
- /* Now, thisitem is first before/at boundary. */
-
- good = netobuf; /* where the good bytes go */
-
- while (netoring.add > thisitem) {
- if (wewant(thisitem)) {
- int length;
-
- next = thisitem;
- do {
- next = nextitem(next);
- } while (wewant(next) && (nfrontp > next));
- length = next-thisitem;
- memcpy(good, thisitem, length);
- good += length;
- thisitem = next;
- } else {
- thisitem = nextitem(thisitem);
- }
- }
-
-#endif /* 0 */
- ring_init(&netoring, netobuf, sizeof netobuf);
-}
-
-#include <varargs.h>
-
-void
-netoprint(va_alist)
-va_dcl
-{
- va_list ap;
- char buffer[100]; /* where things go */
- char *ptr;
- char *format;
- char *string;
- int i;
-
- va_start(ap);
-
- format = va_arg(ap, char *);
- ptr = buffer;
-
- while ((i = *format++) != 0) {
- if (i == '%') {
- i = *format++;
- switch (i) {
- case 'c':
- *ptr++ = va_arg(ap, int);
- break;
- case 's':
- string = va_arg(ap, char *);
- ring_supply_data(&netoring, buffer, ptr-buffer);
- ring_supply_data(&netoring, string, strlen(string));
- ptr = buffer;
- break;
- case 0:
- ExitString("netoprint: trailing %%.\n", 1);
- /*NOTREACHED*/
- default:
- ExitString("netoprint: unknown format character.\n", 1);
- /*NOTREACHED*/
- }
- } else {
- *ptr++ = i;
+ if (n) {
+ ring_consumed(&netoring, n);
+ /*
+ * If we sent all, and more to send, then recurse to pick
+ * up the other half.
+ */
+ if ((n1 == n) && ring_full_consecutive(&netoring)) {
+ (void) netflush();
}
+ return 1;
+ } else {
+ return 0;
}
- ring_supply_data(&netoring, buffer, ptr-buffer);
}