add 1994 copyright
[unix-history] / usr / src / usr.bin / rsh / rsh.c
index 04f1083..6e2c26d 100644 (file)
@@ -1,18 +1,18 @@
 /*-
 /*-
- * Copyright (c) 1983, 1990 The Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1983, 1990, 1993, 1994
+ *     The Regents of the University of California.  All rights reserved.
  *
  * %sccs.include.redist.c%
  */
 
 #ifndef lint
  *
  * %sccs.include.redist.c%
  */
 
 #ifndef lint
-char copyright[] =
-"@(#) Copyright (c) 1983, 1990 The Regents of the University of California.\n\
- All rights reserved.\n";
+static char copyright[] =
+"@(#) Copyright (c) 1983, 1990, 1993, 1994\n\
      The Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */
 
 #ifndef lint
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)rsh.c      5.21 (Berkeley) %G%";
+static char sccsid[] = "@(#)rsh.c      8.3 (Berkeley) %G%";
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -29,11 +29,16 @@ static char sccsid[] = "@(#)rsh.c   5.21 (Berkeley) %G%";
 #include <netinet/in.h>
 #include <netdb.h>
 
 #include <netinet/in.h>
 #include <netdb.h>
 
+#include <err.h>
+#include <errno.h>
 #include <pwd.h>
 #include <pwd.h>
+#include <signal.h>
 #include <stdio.h>
 #include <stdio.h>
-#include <errno.h>
+#include <stdlib.h>
 #include <string.h>
 #include <string.h>
+#include <unistd.h>
 #include <varargs.h>
 #include <varargs.h>
+
 #include "pathnames.h"
 
 #ifdef KERBEROS
 #include "pathnames.h"
 
 #ifdef KERBEROS
@@ -42,7 +47,7 @@ static char sccsid[] = "@(#)rsh.c     5.21 (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;
 extern char *krb_realmofhost();
 #endif
 char dst_realm_buf[REALM_SZ], *dest_realm;
 extern char *krb_realmofhost();
 #endif
@@ -50,29 +55,33 @@ extern char *krb_realmofhost();
 /*
  * rsh - remote shell
  */
 /*
  * rsh - remote shell
  */
-extern int errno;
-int rfd2;
+int    rfd2;
+
+char   *copyargs __P((char **));
+void   sendsig __P((int));
+void   talk __P((int, long, pid_t, int));
+void   usage __P((void));
+void   warning __P(());
 
 
+int
 main(argc, argv)
        int argc;
        char **argv;
 {
 main(argc, argv)
        int argc;
        char **argv;
 {
-       extern char *optarg;
-       extern int optind;
        struct passwd *pw;
        struct servent *sp;
        long omask;
        struct passwd *pw;
        struct servent *sp;
        long omask;
-       int argoff, asrsh, ch, dflag, nflag, one, pid, rem, uid;
-       register char *p;
-       char *args, *host, *user, *copyargs();
-       void sendsig();
+       int argoff, asrsh, ch, dflag, nflag, one, rem;
+       pid_t pid;
+       uid_t uid;
+       char *args, *host, *p, *user;
 
        argoff = asrsh = dflag = nflag = 0;
        one = 1;
        host = user = NULL;
 
        /* if called as something other than "rsh", use it as the host name */
 
        argoff = asrsh = dflag = nflag = 0;
        one = 1;
        host = user = NULL;
 
        /* if called as something other than "rsh", use it as the host name */
-       if (p = rindex(argv[0], '/'))
+       if (p = strrchr(argv[0], '/'))
                ++p;
        else
                p = argv[0];
                ++p;
        else
                p = argv[0];
@@ -88,7 +97,7 @@ main(argc, argv)
        }
 
 #ifdef KERBEROS
        }
 
 #ifdef KERBEROS
-#define        OPTIONS "8KLdek:l:nwx"
+#define        OPTIONS "8KLdek:l:nw"
 #else
 #define        OPTIONS "8KLdel:nw"
 #endif
 #else
 #define        OPTIONS "8KLdel:nw"
 #endif
@@ -120,10 +129,6 @@ main(argc, argv)
                        nflag = 1;
                        break;
 #ifdef KERBEROS
                        nflag = 1;
                        break;
 #ifdef KERBEROS
-               case 'x':
-                       encrypt = 1;
-                       des_set_key(cred.session, schedule);
-                       break;
 #endif
                case '?':
                default:
 #endif
                case '?':
                default:
@@ -140,24 +145,18 @@ main(argc, argv)
                if (asrsh)
                        *argv = "rlogin";
                execv(_PATH_RLOGIN, argv);
                if (asrsh)
                        *argv = "rlogin";
                execv(_PATH_RLOGIN, argv);
-               (void)fprintf(stderr, "rsh: can't exec %s.\n", _PATH_RLOGIN);
-               exit(1);
+               err(1, "can't exec %s", _PATH_RLOGIN);
        }
 
        argc -= optind;
        argv += optind;
 
        }
 
        argc -= optind;
        argv += optind;
 
-       if (!(pw = getpwuid(uid = getuid()))) {
-               (void)fprintf(stderr, "rsh: unknown user id.\n");
-               exit(1);
-       }
+       if (!(pw = getpwuid(uid = getuid())))
+               errx(1, "unknown user id");
        if (!user)
                user = pw->pw_name;
 
 #ifdef KERBEROS
        if (!user)
                user = pw->pw_name;
 
 #ifdef KERBEROS
-       /* -x turns off -n */
-       if (encrypt)
-               nflag = 0;
 #endif
 
        args = copyargs(argv);
 #endif
 
        args = copyargs(argv);
@@ -165,43 +164,41 @@ main(argc, argv)
        sp = NULL;
 #ifdef KERBEROS
        if (use_kerberos) {
        sp = NULL;
 #ifdef KERBEROS
        if (use_kerberos) {
-               sp = getservbyname((encrypt ? "ekshell" : "kshell"), "tcp");
+               sp = getservbyname((doencrypt ? "ekshell" : "kshell"), "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 ? "ekshell" : "kshell");
+                           doencrypt ? "ekshell" : "kshell");
                }
        }
 #endif
        if (sp == NULL)
                sp = getservbyname("shell", "tcp");
                }
        }
 #endif
        if (sp == NULL)
                sp = getservbyname("shell", "tcp");
-       if (sp == NULL) {
-               (void)fprintf(stderr, "rsh: shell/tcp: unknown service.\n");
-               exit(1);
-       }
+       if (sp == NULL)
+               errx(1, "shell/tcp: unknown service");
 
 #ifdef KERBEROS
 try_connect:
        if (use_kerberos) {
 
 #ifdef KERBEROS
 try_connect:
        if (use_kerberos) {
+               struct hostent *hp;
+
+               /* fully qualify hostname (needed for krb_realmofhost) */
+               hp = gethostbyname(host);
+               if (hp != NULL && !(host = strdup(hp->h_name)))
+                       err(1, NULL);
+
                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);
 
-               if (encrypt)
-                       rem = krcmd_mutual(&host, sp->s_port, user, args,
-                           &rfd2, dest_realm, &cred, schedule);
-               else
                        rem = krcmd(&host, sp->s_port, user, args, &rfd2,
                            dest_realm);
                if (rem < 0) {
                        use_kerberos = 0;
                        sp = getservbyname("shell", "tcp");
                        rem = krcmd(&host, sp->s_port, user, args, &rfd2,
                            dest_realm);
                if (rem < 0) {
                        use_kerberos = 0;
                        sp = getservbyname("shell", "tcp");
-                       if (sp == NULL) {
-                               (void)fprintf(stderr,
-                                   "rsh: unknown service shell/tcp.\n");
-                               exit(1);
-                       }
+                       if (sp == NULL)
+                               errx(1, "shell/tcp: unknown service");
                        if (errno == ECONNREFUSED)
                                warning("remote host doesn't support Kerberos");
                        if (errno == ENOENT)
                        if (errno == ECONNREFUSED)
                                warning("remote host doesn't support Kerberos");
                        if (errno == ENOENT)
@@ -209,11 +206,8 @@ try_connect:
                        goto try_connect;
                }
        } else {
                        goto try_connect;
                }
        } else {
-               if (encrypt) {
-                       (void)fprintf(stderr,
-                           "rsh: the -x flag requires Kerberos authentication.\n");
-                       exit(1);
-               }
+               if (doencrypt)
+                       errx(1, "the -x flag requires Kerberos authentication");
                rem = rcmd(&host, sp->s_port, pw->pw_name, user, args, &rfd2);
        }
 #else
                rem = rcmd(&host, sp->s_port, pw->pw_name, user, args, &rfd2);
        }
 #else
@@ -223,19 +217,15 @@ try_connect:
        if (rem < 0)
                exit(1);
 
        if (rem < 0)
                exit(1);
 
-       if (rfd2 < 0) {
-               (void)fprintf(stderr, "rsh: can't establish stderr.\n");
-               exit(1);
-       }
+       if (rfd2 < 0)
+               errx(1, "can't establish stderr");
        if (dflag) {
                if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one,
                    sizeof(one)) < 0)
        if (dflag) {
                if (setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one,
                    sizeof(one)) < 0)
-                       (void)fprintf(stderr, "rsh: setsockopt: %s.\n",
-                           strerror(errno));
+                       warn("setsockopt");
                if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, &one,
                    sizeof(one)) < 0)
                if (setsockopt(rfd2, SOL_SOCKET, SO_DEBUG, &one,
                    sizeof(one)) < 0)
-                       (void)fprintf(stderr, "rsh: setsockopt: %s.\n",
-                           strerror(errno));
+                       warn("setsockopt");
        }
 
        (void)setuid(uid);
        }
 
        (void)setuid(uid);
@@ -249,15 +239,11 @@ try_connect:
 
        if (!nflag) {
                pid = fork();
 
        if (!nflag) {
                pid = fork();
-               if (pid < 0) {
-                       (void)fprintf(stderr,
-                           "rsh: fork: %s.\n", strerror(errno));
-                       exit(1);
-               }
+               if (pid < 0)
+                       err(1, "fork");
        }
 
 #ifdef KERBEROS
        }
 
 #ifdef KERBEROS
-       if (!encrypt)
 #endif
        {
                (void)ioctl(rfd2, FIONBIO, &one);
 #endif
        {
                (void)ioctl(rfd2, FIONBIO, &one);
@@ -271,15 +257,16 @@ try_connect:
        exit(0);
 }
 
        exit(0);
 }
 
+void
 talk(nflag, omask, pid, rem)
 talk(nflag, omask, pid, rem)
-       int nflag, pid;
+       int nflag;
        long omask;
        long omask;
-       register int rem;
+       pid_t pid;
+       int rem;
 {
 {
-       register int cc, wc;
-       register char *bp;
-       int readfrom, ready, rembits;
-       char buf[BUFSIZ];
+       int cc, wc;
+       fd_set readfrom, ready, rembits;
+       char *bp, buf[BUFSIZ];
 
        if (!nflag && pid == 0) {
                (void)close(rfd2);
 
        if (!nflag && pid == 0) {
                (void)close(rfd2);
@@ -289,21 +276,17 @@ reread:           errno = 0;
                        goto done;
                bp = buf;
 
                        goto done;
                bp = buf;
 
-rewrite:       rembits = 1 << rem;
+rewrite:       
+               FD_ZERO(&rembits);
+               FD_SET(rem, &rembits);
                if (select(16, 0, &rembits, 0, 0) < 0) {
                if (select(16, 0, &rembits, 0, 0) < 0) {
-                       if (errno != EINTR) {
-                               (void)fprintf(stderr,
-                                   "rsh: select: %s.\n", strerror(errno));
-                               exit(1);
-                       }
+                       if (errno != EINTR)
+                               err(1, "select");
                        goto rewrite;
                }
                        goto rewrite;
                }
-               if ((rembits & (1 << rem)) == 0)
+               if (!FD_ISSET(rem, &rembits))
                        goto rewrite;
 #ifdef KERBEROS
                        goto rewrite;
 #ifdef KERBEROS
-               if (encrypt)
-                       wc = des_write(rem, bp, cc);
-               else
 #endif
                        wc = write(rem, bp, cc);
                if (wc < 0) {
 #endif
                        wc = write(rem, bp, cc);
                if (wc < 0) {
@@ -322,62 +305,56 @@ done:
        }
 
        (void)sigsetmask(omask);
        }
 
        (void)sigsetmask(omask);
-       readfrom = (1 << rfd2) | (1 << rem);
+       FD_ZERO(&readfrom);
+       FD_SET(rfd2, &readfrom);
+       FD_SET(rem, &readfrom);
        do {
                ready = readfrom;
                if (select(16, &ready, 0, 0, 0) < 0) {
        do {
                ready = readfrom;
                if (select(16, &ready, 0, 0, 0) < 0) {
-                       if (errno != EINTR) {
-                               (void)fprintf(stderr,
-                                   "rsh: select: %s.\n", strerror(errno));
-                               exit(1);
-                       }
+                       if (errno != EINTR)
+                               err(1, "select");
                        continue;
                }
                        continue;
                }
-               if (ready & (1 << rfd2)) {
+               if (FD_ISSET(rfd2, &ready)) {
                        errno = 0;
 #ifdef KERBEROS
                        errno = 0;
 #ifdef KERBEROS
-                       if (encrypt)
-                               cc = des_read(rfd2, buf, sizeof buf);
-                       else
 #endif
                                cc = read(rfd2, buf, sizeof buf);
                        if (cc <= 0) {
                                if (errno != EWOULDBLOCK)
 #endif
                                cc = read(rfd2, buf, sizeof buf);
                        if (cc <= 0) {
                                if (errno != EWOULDBLOCK)
-                                       readfrom &= ~(1 << rfd2);
+                                       FD_CLR(rfd2, &readfrom);
                        } else
                                (void)write(2, buf, cc);
                }
                        } else
                                (void)write(2, buf, cc);
                }
-               if (ready & (1 << rem)) {
+               if (FD_ISSET(rem, &ready)) {
                        errno = 0;
 #ifdef KERBEROS
                        errno = 0;
 #ifdef KERBEROS
-                       if (encrypt)
-                               cc = des_read(rem, buf, sizeof buf);
-                       else
 #endif
                                cc = read(rem, buf, sizeof buf);
                        if (cc <= 0) {
                                if (errno != EWOULDBLOCK)
 #endif
                                cc = read(rem, buf, sizeof buf);
                        if (cc <= 0) {
                                if (errno != EWOULDBLOCK)
-                                       readfrom &= ~(1 << rem);
+                                       FD_CLR(rem, &readfrom);
                        } else
                                (void)write(1, buf, cc);
                }
                        } else
                                (void)write(1, buf, cc);
                }
-       } while (readfrom);
+       } while (FD_ISSET(rfd2, &readfrom) || FD_ISSET(rem, &readfrom));
 }
 
 void
 }
 
 void
-sendsig(signo)
-       char signo;
+sendsig(sig)
+       int sig;
 {
 {
+       char signo;
+
+       signo = sig;
 #ifdef KERBEROS
 #ifdef KERBEROS
-       if (encrypt)
-               (void)des_write(rfd2, &signo, 1);
-       else
 #endif
                (void)write(rfd2, &signo, 1);
 }
 
 #ifdef KERBEROS
 /* VARARGS */
 #endif
                (void)write(rfd2, &signo, 1);
 }
 
 #ifdef KERBEROS
 /* VARARGS */
+void
 warning(va_alist)
 va_dcl
 {
 warning(va_alist)
 va_dcl
 {
@@ -397,34 +374,33 @@ char *
 copyargs(argv)
        char **argv;
 {
 copyargs(argv)
        char **argv;
 {
-       register int cc;
-       register char **ap, *p;
-       char *args, *malloc();
+       int cc;
+       char **ap, *args, *p;
 
        cc = 0;
        for (ap = argv; *ap; ++ap)
                cc += strlen(*ap) + 1;
 
        cc = 0;
        for (ap = argv; *ap; ++ap)
                cc += strlen(*ap) + 1;
-       if (!(args = malloc((u_int)cc))) {
-               (void)fprintf(stderr, "rsh: %s.\n", strerror(ENOMEM));
-               exit(1);
-       }
+       if (!(args = malloc((u_int)cc)))
+               err(1, NULL);
        for (p = args, ap = argv; *ap; ++ap) {
                (void)strcpy(p, *ap);
                for (p = strcpy(p, *ap); *p; ++p);
                if (ap[1])
                        *p++ = ' ';
        }
        for (p = args, ap = argv; *ap; ++ap) {
                (void)strcpy(p, *ap);
                for (p = strcpy(p, *ap); *p; ++p);
                if (ap[1])
                        *p++ = ' ';
        }
-       return(args);
+       return (args);
 }
 
 }
 
+void
 usage()
 {
 usage()
 {
+
        (void)fprintf(stderr,
        (void)fprintf(stderr,
-           "usage: rsh [-ndx]%s[-l login] host [command]\n",
+           "usage: rsh [-nd%s]%s[-l login] host [command]\n",
 #ifdef KERBEROS
 #ifdef KERBEROS
-           " [-k realm] ");
+           "", " [-k realm] ");
 #else
 #else
-           " ");
+           "", " ");
 #endif
        exit(1);
 }
 #endif
        exit(1);
 }