Version 4.0 readme
[unix-history] / usr / src / usr.bin / rlogin / rlogin.c
index ba7ed94..68b2251 100644 (file)
@@ -1,24 +1,39 @@
 /*
 /*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.  The Berkeley software License Agreement
- * specifies the terms and conditions for redistribution.
+ * Copyright (c) 1983 The 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
 char copyright[] =
  */
 
 #ifndef lint
 char copyright[] =
-"@(#) Copyright (c) 1983 Regents of the University of California.\n\
+"@(#) Copyright (c) 1983 The Regents of the University of California.\n\
  All rights reserved.\n";
  All rights reserved.\n";
-#endif not lint
+#endif /* not lint */
 
 #ifndef lint
 
 #ifndef lint
-static char sccsid[] = "@(#)rlogin.c   5.3 (Berkeley) %G%";
-#endif not lint
+static char sccsid[] = "@(#)rlogin.c   5.12 (Berkeley) %G%";
+#endif /* not lint */
 
 /*
  * rlogin - remote login
  */
 
 /*
  * rlogin - remote login
  */
-#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/file.h>
 #include <sys/socket.h>
 #include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/resource.h>
 #include <sys/wait.h>
 
 #include <netinet/in.h>
 #include <sys/wait.h>
 
 #include <netinet/in.h>
@@ -28,10 +43,19 @@ static char sccsid[] = "@(#)rlogin.c        5.3 (Berkeley) %G%";
 #include <errno.h>
 #include <pwd.h>
 #include <signal.h>
 #include <errno.h>
 #include <pwd.h>
 #include <signal.h>
-#include <netdb.h>
 #include <setjmp.h>
 #include <setjmp.h>
+#include <netdb.h>
+
+# ifndef TIOCPKT_WINDOW
+# define TIOCPKT_WINDOW 0x80
+# endif TIOCPKT_WINDOW
 
 
-char   *index(), *rindex(), *malloc(), *getenv();
+/* concession to sun */
+# ifndef SIGUSR1
+# define SIGUSR1 30
+# endif SIGUSR1
+
+char   *index(), *rindex(), *malloc(), *getenv(), *strcat(), *strcpy();
 struct passwd *getpwuid();
 char   *name;
 int    rem;
 struct passwd *getpwuid();
 char   *name;
 int    rem;
@@ -44,10 +68,44 @@ char        *speeds[] =
 char   term[256] = "network";
 extern int errno;
 int    lostpeer();
 char   term[256] = "network";
 extern int errno;
 int    lostpeer();
-int    nosigwin;
-jmp_buf        winsizechanged;
+int    dosigwinch = 0;
+#ifndef sigmask
+#define sigmask(m)     (1 << ((m)-1))
+#endif
+#ifdef sun
+struct winsize {
+       unsigned short ws_row, ws_col;
+       unsigned short ws_xpixel, ws_ypixel;
+};
+#endif sun
 struct winsize winsize;
 struct winsize winsize;
-int    sigwinch();
+int    sigwinch(), oob();
+
+/*
+ * The following routine provides compatibility (such as it is)
+ * between 4.2BSD Suns and others.  Suns have only a `ttysize',
+ * so we convert it to a winsize.
+ */
+#ifdef sun
+int
+get_window_size(fd, wp)
+       int fd;
+       struct winsize *wp;
+{
+       struct ttysize ts;
+       int error;
+
+       if ((error = ioctl(0, TIOCGSIZE, &ts)) != 0)
+               return (error);
+       wp->ws_row = ts.ts_lines;
+       wp->ws_col = ts.ts_cols;
+       wp->ws_xpixel = 0;
+       wp->ws_ypixel = 0;
+       return (0);
+}
+#else sun
+#define get_window_size(fd, wp)        ioctl(fd, TIOCGWINSZ, wp)
+#endif sun
 
 main(argc, argv)
        int argc;
 
 main(argc, argv)
        int argc;
@@ -57,7 +115,7 @@ main(argc, argv)
        struct sgttyb ttyb;
        struct passwd *pwd;
        struct servent *sp;
        struct sgttyb ttyb;
        struct passwd *pwd;
        struct servent *sp;
-       int uid, options = 0;
+       int uid, options = 0, oldmask;
        int on = 1;
 
        host = rindex(argv[0], '/');
        int on = 1;
 
        host = rindex(argv[0], '/');
@@ -96,11 +154,6 @@ another:
                argv++, argc--;
                goto another;
        }
                argv++, argc--;
                goto another;
        }
-       if (argc > 0 && !strcmp(*argv, "-w")) {
-               nosigwin++;
-               argv++, argc--;
-               goto another;
-       }
        if (host == 0)
                goto usage;
        if (argc > 0)
        if (host == 0)
                goto usage;
        if (argc > 0)
@@ -117,17 +170,15 @@ another:
        }
        cp = getenv("TERM");
        if (cp)
        }
        cp = getenv("TERM");
        if (cp)
-               strcpy(term, cp);
+               (void) strcpy(term, cp);
        if (ioctl(0, TIOCGETP, &ttyb) == 0) {
        if (ioctl(0, TIOCGETP, &ttyb) == 0) {
-               strcat(term, "/");
-               strcat(term, speeds[ttyb.sg_ospeed]);
-       }
-       if (!nosigwin && ioctl(0, TIOCGWINSZ, &winsize) == 0) {
-               cp = index(term, '\0');
-               sprintf(cp, "/%u,%u,%u,%u", winsize.ws_row, winsize.ws_col,
-                   winsize.ws_xpixel, winsize.ws_ypixel);
+               (void) strcat(term, "/");
+               (void) strcat(term, speeds[ttyb.sg_ospeed]);
        }
        }
-       signal(SIGPIPE, lostpeer);
+       (void) get_window_size(0, &winsize);
+       (void) signal(SIGPIPE, lostpeer);
+       /* will use SIGUSR1 for window size hack, so hold it off */
+       oldmask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1));
         rem = rcmd(&host, sp->s_port, pwd->pw_name,
            name ? name : pwd->pw_name, term, 0);
         if (rem < 0)
         rem = rcmd(&host, sp->s_port, pwd->pw_name,
            name ? name : pwd->pw_name, term, 0);
         if (rem < 0)
@@ -140,11 +191,11 @@ another:
                perror("rlogin: setuid");
                exit(1);
        }
                perror("rlogin: setuid");
                exit(1);
        }
-       doit();
+       doit(oldmask);
        /*NOTREACHED*/
 usage:
        fprintf(stderr,
        /*NOTREACHED*/
 usage:
        fprintf(stderr,
-           "usage: rlogin host [ -ex ] [ -l username ] [ -8 ] [ -L ] [ -w ]\n");
+           "usage: rlogin host [ -ex ] [ -l username ] [ -8 ] [ -L ]\n");
        exit(1);
 }
 
        exit(1);
 }
 
@@ -152,6 +203,7 @@ usage:
 
 int    child;
 int    catchild();
 
 int    child;
 int    catchild();
+int    copytochild(), writeroob();
 
 int    defflags, tabflag;
 int    deflflags;
 
 int    defflags, tabflag;
 int    deflflags;
@@ -161,53 +213,106 @@ struct   ltchars defltc;
 struct tchars notc =   { -1, -1, -1, -1, -1, -1 };
 struct ltchars noltc = { -1, -1, -1, -1, -1, -1 };
 
 struct tchars notc =   { -1, -1, -1, -1, -1, -1 };
 struct ltchars noltc = { -1, -1, -1, -1, -1, -1 };
 
-doit()
+doit(oldmask)
 {
        int exit();
        struct sgttyb sb;
 
 {
        int exit();
        struct sgttyb sb;
 
-       ioctl(0, TIOCGETP, (char *)&sb);
+       (void) ioctl(0, TIOCGETP, (char *)&sb);
        defflags = sb.sg_flags;
        tabflag = defflags & TBDELAY;
        defflags &= ECHO | CRMOD;
        deferase = sb.sg_erase;
        defkill = sb.sg_kill;
        defflags = sb.sg_flags;
        tabflag = defflags & TBDELAY;
        defflags &= ECHO | CRMOD;
        deferase = sb.sg_erase;
        defkill = sb.sg_kill;
-       ioctl(0, TIOCLGET, (char *)&deflflags);
-       ioctl(0, TIOCGETC, (char *)&deftc);
+       (void) ioctl(0, TIOCLGET, (char *)&deflflags);
+       (void) ioctl(0, TIOCGETC, (char *)&deftc);
        notc.t_startc = deftc.t_startc;
        notc.t_stopc = deftc.t_stopc;
        notc.t_startc = deftc.t_startc;
        notc.t_stopc = deftc.t_stopc;
-       ioctl(0, TIOCGLTC, (char *)&defltc);
-       signal(SIGINT, exit);
-       signal(SIGHUP, exit);
-       signal(SIGQUIT, exit);
+       (void) ioctl(0, TIOCGLTC, (char *)&defltc);
+       (void) signal(SIGINT, SIG_IGN);
+       setsignal(SIGHUP, exit);
+       setsignal(SIGQUIT, exit);
        child = fork();
        if (child == -1) {
                perror("rlogin: fork");
        child = fork();
        if (child == -1) {
                perror("rlogin: fork");
-               done();
+               done(1);
        }
        }
-       signal(SIGINT, SIG_IGN);
-       mode(1);
        if (child == 0) {
        if (child == 0) {
-               reader();
+               mode(1);
+               if (reader(oldmask) == 0) {
+                       prf("Connection closed.");
+                       exit(0);
+               }
                sleep(1);
                prf("\007Connection closed.");
                exit(3);
        }
                sleep(1);
                prf("\007Connection closed.");
                exit(3);
        }
-       signal(SIGCHLD, catchild);
-       if (!nosigwin)
-               signal(SIGWINCH, sigwinch);
+
+       /*
+        * We may still own the socket, and may have a pending SIGURG
+        * (or might receive one soon) that we really want to send to
+        * the reader.  Set a trap that simply copies such signals to
+        * the child.
+        */
+       (void) signal(SIGURG, copytochild);
+       (void) signal(SIGUSR1, writeroob);
+       (void) sigsetmask(oldmask);
+       (void) signal(SIGCHLD, catchild);
        writer();
        prf("Closed connection.");
        writer();
        prf("Closed connection.");
-       done();
+       done(0);
 }
 
 }
 
-done()
+/*
+ * Trap a signal, unless it is being ignored.
+ */
+setsignal(sig, act)
+       int sig, (*act)();
 {
 {
+       int omask = sigblock(sigmask(sig));
+
+       if (signal(sig, act) == SIG_IGN)
+               (void) signal(sig, SIG_IGN);
+       (void) sigsetmask(omask);
+}
+
+done(status)
+       int status;
+{
+       int w;
 
        mode(0);
 
        mode(0);
-       if (child > 0 && kill(child, SIGKILL) >= 0)
-               wait((int *)0);
-       exit(0);
+       if (child > 0) {
+               /* make sure catchild does not snap it up */
+               (void) signal(SIGCHLD, SIG_DFL);
+               if (kill(child, SIGKILL) >= 0)
+                       while ((w = wait((union wait *)0)) > 0 && w != child)
+                               /*void*/;
+       }
+       exit(status);
+}
+
+/*
+ * Copy SIGURGs to the child process.
+ */
+copytochild()
+{
+
+       (void) kill(child, SIGURG);
+}
+
+/*
+ * This is called when the reader process gets the out-of-band (urgent)
+ * request to turn on the window-changing protocol.
+ */
+writeroob()
+{
+
+       if (dosigwinch == 0) {
+               sendwindow();
+               (void) signal(SIGWINCH, sigwinch);
+       }
+       dosigwinch = 1;
 }
 
 catchild()
 }
 
 catchild()
@@ -216,14 +321,14 @@ catchild()
        int pid;
 
 again:
        int pid;
 
 again:
-       pid = wait3(&status, WNOHANG|WUNTRACED, 0);
+       pid = wait3(&status, WNOHANG|WUNTRACED, (struct rusage *)0);
        if (pid == 0)
                return;
        /*
         * if the child (reader) dies, just quit
         */
        if (pid < 0 || pid == child && !WIFSTOPPED(status))
        if (pid == 0)
                return;
        /*
         * if the child (reader) dies, just quit
         */
        if (pid < 0 || pid == child && !WIFSTOPPED(status))
-               done();
+               done((int)(status.w_termsig | status.w_retcode));
        goto again;
 }
 
        goto again;
 }
 
@@ -240,33 +345,6 @@ writer()
        register bol = 1;               /* beginning of line */
        register local = 0;
 
        register bol = 1;               /* beginning of line */
        register local = 0;
 
-       /*
-        * Handle SIGWINCH's with in-band signaling of new
-        * window size.  It seems reasonable that we flush
-        * pending input and not force out of band signal
-        * as this most likely will occur from an input device
-        * other than the keyboard (e.g. a mouse).
-        *
-        * The hack of using 0377 to signal an in-band signal
-        * is pretty bad, but otherwise we'd be forced to
-        * either get complicated (use MSG_OOB) or go to a
-        * serious (telnet-style) protocol.
-        */
-       if (setjmp(winsizechanged)) {
-               char obuf[4 + sizeof (struct winsize)];
-               struct winsize *wp = (struct winsize *)(obuf+4);
-
-               obuf[0] = 0377;                 /* XXX */
-               obuf[1] = 0377;                 /* XXX */
-               obuf[2] = 's';                  /* XXX */
-               obuf[3] = 's';                  /* XXX */
-               wp->ws_row = htons(winsize.ws_row);
-               wp->ws_col = htons(winsize.ws_col);
-               wp->ws_xpixel = htons(winsize.ws_xpixel);
-               wp->ws_ypixel = htons(winsize.ws_ypixel);
-               (void) write(rem, obuf, 4+sizeof (*wp));
-       }
-
        for (;;) {
                n = read(0, &c, 1);
                if (n <= 0) {
        for (;;) {
                n = read(0, &c, 1);
                if (n <= 0) {
@@ -274,8 +352,6 @@ writer()
                                continue;
                        break;
                }
                                continue;
                        break;
                }
-               if (!eight)
-                       c &= 0177;
                /*
                 * If we're at the beginning of the line
                 * and recognize a command character, then
                /*
                 * If we're at the beginning of the line
                 * and recognize a command character, then
@@ -304,13 +380,14 @@ writer()
                                continue;
                        }
                        if (c != cmdchar)
                                continue;
                        }
                        if (c != cmdchar)
-                               write(rem, &cmdchar, 1);
+                               (void) write(rem, &cmdchar, 1);
                }
                if (write(rem, &c, 1) == 0) {
                        prf("line gone");
                        break;
                }
                bol = c == defkill || c == deftc.t_eofc ||
                }
                if (write(rem, &c, 1) == 0) {
                        prf("line gone");
                        break;
                }
                bol = c == defkill || c == deftc.t_eofc ||
+                   c == deftc.t_intrc || c == defltc.t_suspc ||
                    c == '\r' || c == '\n';
        }
 }
                    c == '\r' || c == '\n';
        }
 }
@@ -333,18 +410,16 @@ register char c;
                *p++ = c;
        *p++ = '\r';
        *p++ = '\n';
                *p++ = c;
        *p++ = '\r';
        *p++ = '\n';
-       write(1, buf, p - buf);
+       (void) write(1, buf, p - buf);
 }
 
 stop(cmdc)
        char cmdc;
 {
 }
 
 stop(cmdc)
        char cmdc;
 {
-       struct winsize ws;
-
        mode(0);
        mode(0);
-       signal(SIGCHLD, SIG_IGN);
-       kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP);
-       signal(SIGCHLD, catchild);
+       (void) signal(SIGCHLD, SIG_IGN);
+       (void) kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP);
+       (void) signal(SIGCHLD, catchild);
        mode(1);
        sigwinch();                     /* check for size changes */
 }
        mode(1);
        sigwinch();                     /* check for size changes */
 }
@@ -353,64 +428,181 @@ sigwinch()
 {
        struct winsize ws;
 
 {
        struct winsize ws;
 
-       if (!nosigwin && ioctl(0, TIOCGWINSZ, &ws) == 0 &&
+       if (dosigwinch && get_window_size(0, &ws) == 0 &&
            bcmp(&ws, &winsize, sizeof (ws))) {
                winsize = ws;
            bcmp(&ws, &winsize, sizeof (ws))) {
                winsize = ws;
-               longjmp(winsizechanged, 1);
+               sendwindow();
        }
 }
 
        }
 }
 
+/*
+ * Send the window size to the server via the magic escape
+ */
+sendwindow()
+{
+       char obuf[4 + sizeof (struct winsize)];
+       struct winsize *wp = (struct winsize *)(obuf+4);
+
+       obuf[0] = 0377;
+       obuf[1] = 0377;
+       obuf[2] = 's';
+       obuf[3] = 's';
+       wp->ws_row = htons(winsize.ws_row);
+       wp->ws_col = htons(winsize.ws_col);
+       wp->ws_xpixel = htons(winsize.ws_xpixel);
+       wp->ws_ypixel = htons(winsize.ws_ypixel);
+       (void) write(rem, obuf, sizeof(obuf));
+}
+
+/*
+ * reader: read from remote: line -> 1
+ */
+#define        READING 1
+#define        WRITING 2
+
+char   rcvbuf[8 * 1024];
+int    rcvcnt;
+int    rcvstate;
+int    ppid;
+jmp_buf        rcvtop;
+
 oob()
 {
 oob()
 {
-       int out = 1+1, atmark;
+       int out = FWRITE, atmark, n;
+       int rcvd = 0;
        char waste[BUFSIZ], mark;
        char waste[BUFSIZ], mark;
+       struct sgttyb sb;
 
 
-       ioctl(1, TIOCFLUSH, (char *)&out);
-       for (;;) {
-               if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
-                       perror("ioctl");
-                       break;
-               }
-               if (atmark)
-                       break;
-               if (read(rem, waste, sizeof (waste)) <= 0)
-                       break;
+       while (recv(rem, &mark, 1, MSG_OOB) < 0)
+               switch (errno) {
+               
+               case EWOULDBLOCK:
+                       /*
+                        * Urgent data not here yet.
+                        * It may not be possible to send it yet
+                        * if we are blocked for output
+                        * and our input buffer is full.
+                        */
+                       if (rcvcnt < sizeof(rcvbuf)) {
+                               n = read(rem, rcvbuf + rcvcnt,
+                                       sizeof(rcvbuf) - rcvcnt);
+                               if (n <= 0)
+                                       return;
+                               rcvd += n;
+                       } else {
+                               n = read(rem, waste, sizeof(waste));
+                               if (n <= 0)
+                                       return;
+                       }
+                       continue;
+                               
+               default:
+                       return;
        }
        }
-       recv(rem, &mark, 1, MSG_OOB);
-       if (mark & TIOCPKT_NOSTOP) {
+       if (mark & TIOCPKT_WINDOW) {
+               /*
+                * Let server know about window size changes
+                */
+               (void) kill(ppid, SIGUSR1);
+       }
+       if (!eight && (mark & TIOCPKT_NOSTOP)) {
+               (void) ioctl(0, TIOCGETP, (char *)&sb);
+               sb.sg_flags &= ~CBREAK;
+               sb.sg_flags |= RAW;
+               (void) ioctl(0, TIOCSETN, (char *)&sb);
                notc.t_stopc = -1;
                notc.t_startc = -1;
                notc.t_stopc = -1;
                notc.t_startc = -1;
-               ioctl(0, TIOCSETC, (char *)&notc);
+               (void) ioctl(0, TIOCSETC, (char *)&notc);
        }
        }
-       if (mark & TIOCPKT_DOSTOP) {
+       if (!eight && (mark & TIOCPKT_DOSTOP)) {
+               (void) ioctl(0, TIOCGETP, (char *)&sb);
+               sb.sg_flags &= ~RAW;
+               sb.sg_flags |= CBREAK;
+               (void) ioctl(0, TIOCSETN, (char *)&sb);
                notc.t_stopc = deftc.t_stopc;
                notc.t_startc = deftc.t_startc;
                notc.t_stopc = deftc.t_stopc;
                notc.t_startc = deftc.t_startc;
-               ioctl(0, TIOCSETC, (char *)&notc);
+               (void) ioctl(0, TIOCSETC, (char *)&notc);
        }
        }
+       if (mark & TIOCPKT_FLUSHWRITE) {
+               (void) ioctl(1, TIOCFLUSH, (char *)&out);
+               for (;;) {
+                       if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
+                               perror("ioctl");
+                               break;
+                       }
+                       if (atmark)
+                               break;
+                       n = read(rem, waste, sizeof (waste));
+                       if (n <= 0)
+                               break;
+               }
+               /*
+                * Don't want any pending data to be output,
+                * so clear the recv buffer.
+                * If we were hanging on a write when interrupted,
+                * don't want it to restart.  If we were reading,
+                * restart anyway.
+                */
+               rcvcnt = 0;
+               longjmp(rcvtop, 1);
+       }
+
+       /*
+        * oob does not do FLUSHREAD (alas!)
+        */
+
+       /*
+        * If we filled the receive buffer while a read was pending,
+        * longjmp to the top to restart appropriately.  Don't abort
+        * a pending write, however, or we won't know how much was written.
+        */
+       if (rcvd && rcvstate == READING)
+               longjmp(rcvtop, 1);
 }
 
 /*
  * reader: read from remote: line -> 1
  */
 }
 
 /*
  * reader: read from remote: line -> 1
  */
-reader()
+reader(oldmask)
+       int oldmask;
 {
 {
-       char rb[BUFSIZ];
-       register int cnt;
-
-       signal(SIGURG, oob);
-       signal(SIGTTOU, SIG_IGN);
-       { int pid = -getpid();
-         ioctl(rem, SIOCSPGRP, (char *)&pid); }
+#if !defined(BSD) || BSD < 43
+       int pid = -getpid();
+#else
+       int pid = getpid();
+#endif
+       int n, remaining;
+       char *bufp = rcvbuf;
+
+       (void) signal(SIGTTOU, SIG_IGN);
+       (void) signal(SIGURG, oob);
+       ppid = getppid();
+       (void) fcntl(rem, F_SETOWN, pid);
+       (void) setjmp(rcvtop);
+       (void) sigsetmask(oldmask);
        for (;;) {
        for (;;) {
-               cnt = read(rem, rb, sizeof (rb));
-               if (cnt == 0)
-                       break;
-               if (cnt < 0) {
+               while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) {
+                       rcvstate = WRITING;
+                       n = write(1, bufp, remaining);
+                       if (n < 0) {
+                               if (errno != EINTR)
+                                       return (-1);
+                               continue;
+                       }
+                       bufp += n;
+               }
+               bufp = rcvbuf;
+               rcvcnt = 0;
+               rcvstate = READING;
+               rcvcnt = read(rem, rcvbuf, sizeof (rcvbuf));
+               if (rcvcnt == 0)
+                       return (0);
+               if (rcvcnt < 0) {
                        if (errno == EINTR)
                                continue;
                        if (errno == EINTR)
                                continue;
-                       break;
+                       perror("read");
+                       return (-1);
                }
                }
-               write(1, rb, cnt);
        }
 }
 
        }
 }
 
@@ -421,8 +613,8 @@ mode(f)
        struct sgttyb sb;
        int     lflags;
 
        struct sgttyb sb;
        int     lflags;
 
-       ioctl(0, TIOCGETP, (char *)&sb);
-       ioctl(0, TIOCLGET, (char *)&lflags);
+       (void) ioctl(0, TIOCGETP, (char *)&sb);
+       (void) ioctl(0, TIOCLGET, (char *)&lflags);
        switch (f) {
 
        case 0:
        switch (f) {
 
        case 0:
@@ -451,23 +643,25 @@ mode(f)
        default:
                return;
        }
        default:
                return;
        }
-       ioctl(0, TIOCSLTC, (char *)ltc);
-       ioctl(0, TIOCSETC, (char *)tc);
-       ioctl(0, TIOCSETN, (char *)&sb);
-       ioctl(0, TIOCLSET, (char *)&lflags);
+       (void) ioctl(0, TIOCSLTC, (char *)ltc);
+       (void) ioctl(0, TIOCSETC, (char *)tc);
+       (void) ioctl(0, TIOCSETN, (char *)&sb);
+       (void) ioctl(0, TIOCLSET, (char *)&lflags);
 }
 
 /*VARARGS*/
 }
 
 /*VARARGS*/
-prf(f, a1, a2, a3)
+prf(f, a1, a2, a3, a4, a5)
        char *f;
 {
        char *f;
 {
-       fprintf(stderr, f, a1, a2, a3);
+
+       fprintf(stderr, f, a1, a2, a3, a4, a5);
        fprintf(stderr, CRLF);
 }
 
 lostpeer()
 {
        fprintf(stderr, CRLF);
 }
 
 lostpeer()
 {
-       signal(SIGPIPE, SIG_IGN);
+
+       (void) signal(SIGPIPE, SIG_IGN);
        prf("\007Connection closed.");
        prf("\007Connection closed.");
-       done();
+       done(1);
 }
 }