- ioctl(pty, TIOCGETP, &b);
- if (b.sg_flags & RAW) {
- *pfrontp++ = '\0';
- return;
- }
- *pfrontp++ = ioctl(pty, TIOCGETC, &tchars) < 0 ?
- '\034' : tchars.t_quitc;
-}
-
-ptyflush()
-{
- int n;
-
- if ((n = pfrontp - pbackp) > 0)
- n = write(pty, pbackp, n);
- if (n < 0)
- return;
- pbackp += n;
- if (pbackp == pfrontp)
- pbackp = pfrontp = ptyobuf;
-}
-\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.
- */
-
-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.
- */
-
-netclear()
-{
- 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)) <= nbackp) {
- thisitem = next;
- }
-
- /* Now, thisitem is first before/at boundary. */
-
- good = netobuf; /* where the good bytes go */
-
- while (nfrontp > thisitem) {
- if (wewant(thisitem)) {
- int length;
-
- next = thisitem;
- do {
- next = nextitem(next);
- } while (wewant(next) && (nfrontp > next));
- length = next-thisitem;
- bcopy(thisitem, good, length);
- good += length;
- thisitem = next;
- } else {
- thisitem = nextitem(thisitem);
- }
- }
-
- nbackp = netobuf;
- nfrontp = good; /* next byte to be sent */
- neturg = 0;
-}
-\f
-/*
- * netflush
- * Send as much data as possible to the network,
- * handling requests for urgent data.
- */
-
-
-netflush()
-{
- int n;
-
- if ((n = nfrontp - nbackp) > 0) {
- /*
- * if no urgent data, or if the other side appears to be an
- * old 4.2 client (and thus unable to survive TCP urgent data),
- * write the entire buffer in non-OOB mode.
- */
- if ((neturg == 0) || (not42 == 0)) {
- n = write(net, nbackp, n); /* normal write */
- } else {
- n = neturg - nbackp;
- /*
- * In 4.2 (and 4.3) systems, there is some question about
- * what byte in a sendOOB operation is the "OOB" data.
- * To make ourselves compatible, we only send ONE byte
- * out of band, the one WE THINK should be OOB (though
- * we really have more the TCP philosophy of urgent data
- * rather than the Unix philosophy of OOB data).
- */
- if (n > 1) {
- n = send(net, nbackp, n-1, 0); /* send URGENT all by itself */
- } else {
- n = send(net, nbackp, n, MSG_OOB); /* URGENT data */
- }
- }
- }
- if (n < 0) {
- if (errno == EWOULDBLOCK)
- return;
- /* should blow this guy away... */
- return;
- }
- nbackp += n;
- if (nbackp >= neturg) {
- neturg = 0;
- }
- if (nbackp == nfrontp) {
- nbackp = nfrontp = netobuf;
- }
-}
-
-cleanup()
-{
-
- rmut();
- vhangup(); /* XXX */
- shutdown(net, 2);
- exit(1);
-}
-
-#include <utmp.h>
-
-struct utmp wtmp;
-char wtmpf[] = "/usr/adm/wtmp";
-char utmpf[] = "/etc/utmp";
-#define SCPYN(a, b) strncpy(a, b, sizeof(a))
-#define SCMPN(a, b) strncmp(a, b, sizeof(a))
-
-rmut()
-{
- register f;
- int found = 0;
- struct utmp *u, *utmp;
- int nutmp;
- struct stat statbf;
-
- f = open(utmpf, O_RDWR);
- if (f >= 0) {
- fstat(f, &statbf);
- utmp = (struct utmp *)malloc(statbf.st_size);
- if (!utmp)
- syslog(LOG_ERR, "utmp malloc failed");
- if (statbf.st_size && utmp) {
- nutmp = read(f, utmp, statbf.st_size);
- nutmp /= sizeof(struct utmp);
-
- for (u = utmp ; u < &utmp[nutmp] ; u++) {
- if (SCMPN(u->ut_line, line+5) ||
- u->ut_name[0]==0)
- continue;
- lseek(f, ((long)u)-((long)utmp), L_SET);
- SCPYN(u->ut_name, "");
- SCPYN(u->ut_host, "");
- time(&u->ut_time);
- write(f, (char *)u, sizeof(wtmp));
- found++;
- }
- }
- close(f);
- }
- if (found) {
- f = open(wtmpf, O_WRONLY|O_APPEND);
- if (f >= 0) {
- SCPYN(wtmp.ut_line, line+5);
- SCPYN(wtmp.ut_name, "");
- SCPYN(wtmp.ut_host, "");
- time(&wtmp.ut_time);
- write(f, (char *)&wtmp, sizeof(wtmp));
- close(f);
- }
- }
- chmod(line, 0666);
- chown(line, 0, 0);
- line[strlen("/dev/")] = 'p';
- chmod(line, 0666);
- chown(line, 0, 0);