narrow possible window for losing window size change
[unix-history] / usr / src / usr.bin / rlogin / rlogin.c
index 42ef90f..db58360 100644 (file)
@@ -12,7 +12,7 @@ char copyright[] =
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)rlogin.c   5.32 (Berkeley) %G%";
+static char sccsid[] = "@(#)rlogin.c   5.37 (Berkeley) %G%";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -52,7 +52,7 @@ static char sccsid[] = "@(#)rlogin.c  5.32 (Berkeley) %G%";
 
 CREDENTIALS cred;
 Key_schedule schedule;
 
 CREDENTIALS cred;
 Key_schedule schedule;
-int use_kerberos = 1, encrypt;
+int use_kerberos = 1, doencrypt;
 char dst_realm_buf[REALM_SZ], *dest_realm = NULL;
 extern char *krb_realmofhost();
 #endif
 char dst_realm_buf[REALM_SZ], *dest_realm = NULL;
 extern char *krb_realmofhost();
 #endif
@@ -66,7 +66,6 @@ extern char *krb_realmofhost();
 #define        SIGUSR1 30
 #endif
 
 #define        SIGUSR1 30
 #endif
 
-extern int errno;
 int eight, litout, rem;
 
 int noescape;
 int eight, litout, rem;
 
 int noescape;
@@ -99,11 +98,12 @@ main(argc, argv)
        extern int optind;
        struct passwd *pw;
        struct servent *sp;
        extern int optind;
        struct passwd *pw;
        struct servent *sp;
+       struct hostent *hp;
        struct sgttyb ttyb;
        long omask;
        int argoff, ch, dflag, one, uid;
        char *host, *p, *user, term[1024];
        struct sgttyb ttyb;
        long omask;
        int argoff, ch, dflag, one, uid;
        char *host, *p, *user, term[1024];
-       void lostpeer();
+       void lostpeer(), copytochild(), writeroob();
        u_char getescape();
        char *getenv();
 
        u_char getescape();
        char *getenv();
 
@@ -150,6 +150,7 @@ main(argc, argv)
                        dflag = 1;
                        break;
                case 'e':
                        dflag = 1;
                        break;
                case 'e':
+                       noescape = 0;
                        escapechar = getescape(optarg);
                        break;
 #ifdef KERBEROS
                        escapechar = getescape(optarg);
                        break;
 #ifdef KERBEROS
@@ -161,14 +162,6 @@ main(argc, argv)
                case 'l':
                        user = optarg;
                        break;
                case 'l':
                        user = optarg;
                        break;
-#ifdef CRYPT
-#ifdef KERBEROS
-               case 'x':
-                       encrypt = 1;
-                       des_set_key(cred.session, schedule);
-                       break;
-#endif
-#endif
                case '?':
                default:
                        usage();
                case '?':
                default:
                        usage();
@@ -194,11 +187,11 @@ main(argc, argv)
        sp = NULL;
 #ifdef KERBEROS
        if (use_kerberos) {
        sp = NULL;
 #ifdef KERBEROS
        if (use_kerberos) {
-               sp = getservbyname((encrypt ? "eklogin" : "klogin"), "tcp");
+               sp = getservbyname((doencrypt ? "eklogin" : "klogin"), "tcp");
                if (sp == NULL) {
                        use_kerberos = 0;
                        warning("can't get entry for %s/tcp service",
                if (sp == NULL) {
                        use_kerberos = 0;
                        warning("can't get entry for %s/tcp service",
-                           encrypt ? "eklogin" : "klogin");
+                           doencrypt ? "eklogin" : "klogin");
                }
        }
 #endif
                }
        }
 #endif
@@ -220,21 +213,30 @@ main(argc, argv)
        (void)signal(SIGPIPE, lostpeer);
        /* will use SIGUSR1 for window size hack, so hold it off */
        omask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1));
        (void)signal(SIGPIPE, lostpeer);
        /* will use SIGUSR1 for window size hack, so hold it off */
        omask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1));
+       /*
+        * We set SIGURG and SIGUSR1 below so that an
+        * incoming signal will be held pending rather than being
+        * discarded. Note that these routines will be ready to get
+        * a signal by the time that they are unblocked below.
+        */
+       (void)signal(SIGURG, copytochild);
+       (void)signal(SIGUSR1, writeroob);
 
 #ifdef KERBEROS
 try_connect:
        if (use_kerberos) {
 
 #ifdef KERBEROS
 try_connect:
        if (use_kerberos) {
+               /* fully qualify hostname (needed for krb_realmofhost) */
+               hp = gethostbyname(host);
+               if (hp != NULL && !(host = strdup(hp->h_name))) {
+                       (void)fprintf(stderr, "rlogin: %s.\n", strerror(ENOMEM));
+                       exit(1);
+               }
+
                rem = KSUCCESS;
                errno = 0;
                if (dest_realm == NULL)
                        dest_realm = krb_realmofhost(host);
 
                rem = KSUCCESS;
                errno = 0;
                if (dest_realm == NULL)
                        dest_realm = krb_realmofhost(host);
 
-#ifdef CRYPT
-               if (encrypt)
-                       rem = krcmd_mutual(&host, sp->s_port, user, term, 0,
-                           dest_realm, &cred, schedule);
-               else
-#endif /* CRYPT */
                        rem = krcmd(&host, sp->s_port, user, term, 0,
                            dest_realm);
                if (rem < 0) {
                        rem = krcmd(&host, sp->s_port, user, term, 0,
                            dest_realm);
                if (rem < 0) {
@@ -252,13 +254,6 @@ try_connect:
                        goto try_connect;
                }
        } else {
                        goto try_connect;
                }
        } else {
-#ifdef CRYPT
-               if (encrypt) {
-                       (void)fprintf(stderr,
-                           "rlogin: the -x flag requires Kerberos authentication.\n");
-                       exit(1);
-               }
-#endif /* CRYPT */
                rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0);
        }
 #else
                rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0);
        }
 #else
@@ -292,7 +287,7 @@ doit(omask)
        long omask;
 {
        struct sgttyb sb;
        long omask;
 {
        struct sgttyb sb;
-       void catch_child(), copytochild(), exit(), writeroob();
+       void catch_child(), exit();
 
        (void)ioctl(0, TIOCGETP, (char *)&sb);
        defflags = sb.sg_flags;
 
        (void)ioctl(0, TIOCGETP, (char *)&sb);
        defflags = sb.sg_flags;
@@ -326,11 +321,11 @@ doit(omask)
 
        /*
         * We may still own the socket, and may have a pending SIGURG (or might
 
        /*
         * 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.
+        * receive one soon) that we really want to send to the reader.  When
+        * one of these comes in, the trap copytochild simply copies such
+        * signals to the child. We can now unblock SIGURG and SIGUSR1
+        * that were set above.
         */
         */
-       (void)signal(SIGURG, copytochild);
-       (void)signal(SIGUSR1, writeroob);
        (void)sigsetmask(omask);
        (void)signal(SIGCHLD, catch_child);
        writer();
        (void)sigsetmask(omask);
        (void)signal(SIGCHLD, catch_child);
        writer();
@@ -353,19 +348,20 @@ setsignal(sig, act)
 done(status)
        int status;
 {
 done(status)
        int status;
 {
-       int w;
+       int w, wstatus;
 
        mode(0);
        if (child > 0) {
                /* make sure catch_child does not snap it up */
                (void)signal(SIGCHLD, SIG_DFL);
                if (kill(child, SIGKILL) >= 0)
 
        mode(0);
        if (child > 0) {
                /* make sure catch_child does not snap it up */
                (void)signal(SIGCHLD, SIG_DFL);
                if (kill(child, SIGKILL) >= 0)
-                       while ((w = wait((union wait *)0)) > 0 && w != child);
+                       while ((w = wait(&wstatus)) > 0 && w != child);
        }
        exit(status);
 }
 
 int dosigwinch;
        }
        exit(status);
 }
 
 int dosigwinch;
+void sigwinch();
 
 /*
  * This is called when the reader process gets the out-of-band (urgent)
 
 /*
  * This is called when the reader process gets the out-of-band (urgent)
@@ -374,8 +370,6 @@ int dosigwinch;
 void
 writeroob()
 {
 void
 writeroob()
 {
-       void sigwinch();
-
        if (dosigwinch == 0) {
                sendwindow();
                (void)signal(SIGWINCH, sigwinch);
        if (dosigwinch == 0) {
                sendwindow();
                (void)signal(SIGWINCH, sigwinch);
@@ -390,7 +384,7 @@ catch_child()
        int pid;
 
        for (;;) {
        int pid;
 
        for (;;) {
-               pid = wait3(&status, WNOHANG|WUNTRACED, (struct rusage *)0);
+               pid = wait3((int *)&status, WNOHANG|WUNTRACED, NULL);
                if (pid == 0)
                        return;
                /* if the child (reader) dies, just quit */
                if (pid == 0)
                        return;
                /* if the child (reader) dies, just quit */
@@ -446,26 +440,9 @@ writer()
                                continue;
                        }
                        if (c != escapechar)
                                continue;
                        }
                        if (c != escapechar)
-#ifdef CRYPT
-#ifdef KERBEROS
-                               if (encrypt)
-                                       (void)des_write(rem, &escapechar, 1);
-                               else
-#endif
-#endif
                                        (void)write(rem, &escapechar, 1);
                }
 
                                        (void)write(rem, &escapechar, 1);
                }
 
-#ifdef CRYPT
-#ifdef KERBEROS
-               if (encrypt) {
-                       if (des_write(rem, &c, 1) == 0) {
-                               msg("line gone");
-                               break;
-                       }
-               } else
-#endif
-#endif
                        if (write(rem, &c, 1) == 0) {
                                msg("line gone");
                                break;
                        if (write(rem, &c, 1) == 0) {
                                msg("line gone");
                                break;
@@ -539,13 +516,6 @@ sendwindow()
        wp->ws_xpixel = htons(winsize.ws_xpixel);
        wp->ws_ypixel = htons(winsize.ws_ypixel);
 
        wp->ws_xpixel = htons(winsize.ws_xpixel);
        wp->ws_ypixel = htons(winsize.ws_ypixel);
 
-#ifdef CRYPT
-#ifdef KERBEROS
-       if(encrypt)
-               (void)des_write(rem, obuf, sizeof(obuf));
-       else
-#endif
-#endif
                (void)write(rem, obuf, sizeof(obuf));
 }
 
                (void)write(rem, obuf, sizeof(obuf));
 }
 
@@ -683,13 +653,6 @@ reader(omask)
                rcvcnt = 0;
                rcvstate = READING;
 
                rcvcnt = 0;
                rcvstate = READING;
 
-#ifdef CRYPT
-#ifdef KERBEROS
-               if (encrypt)
-                       rcvcnt = des_read(rem, rcvbuf, sizeof(rcvbuf));
-               else
-#endif
-#endif
                        rcvcnt = read(rem, rcvbuf, sizeof (rcvbuf));
                if (rcvcnt == 0)
                        return (0);
                        rcvcnt = read(rem, rcvbuf, sizeof (rcvbuf));
                if (rcvcnt == 0)
                        return (0);
@@ -786,11 +749,7 @@ usage()
        (void)fprintf(stderr,
            "usage: rlogin [ -%s]%s[-e char] [ -l username ] host\n",
 #ifdef KERBEROS
        (void)fprintf(stderr,
            "usage: rlogin [ -%s]%s[-e char] [ -l username ] host\n",
 #ifdef KERBEROS
-#ifdef CRYPT
-           "8ELx", " [-k realm] ");
-#else
-           "8EL", " [-k realm] ");
-#endif
+           "8EKL", " [-k realm] ");
 #else
            "8EL", " ");
 #endif
 #else
            "8EL", " ");
 #endif