[BACK]Return to rlogin.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.bin / rlogin

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/usr.bin/rlogin/rlogin.c between version 1.14 and 1.15

version 1.14, 1996/08/10 19:47:32 version 1.15, 1997/01/09 06:57:46
Line 41  static char copyright[] =
Line 41  static char copyright[] =
   
 #ifndef lint  #ifndef lint
 #if 0  #if 0
 static char sccsid[] = "@(#)rlogin.c    8.1 (Berkeley) 6/6/93";  static char sccsid[] = "@(#)rlogin.c    8.4 (Berkeley) 4/29/95";
 #else  #else
 static char rcsid[] = "$NetBSD$";  static char rcsid[] = "$NetBSD$";
 #endif  #endif
Line 56  static char rcsid[] = "$NetBSD$";
Line 56  static char rcsid[] = "$NetBSD$";
 #include <sys/time.h>  #include <sys/time.h>
 #include <sys/resource.h>  #include <sys/resource.h>
 #include <sys/wait.h>  #include <sys/wait.h>
   #include <sys/ioctl.h>
   
 #include <netinet/in.h>  #include <netinet/in.h>
 #include <netinet/in_systm.h>  #include <netinet/in_systm.h>
Line 122  struct winsize winsize;
Line 123  struct winsize winsize;
   
 void            catch_child __P((int));  void            catch_child __P((int));
 void            copytochild __P((int));  void            copytochild __P((int));
 __dead void     doit __P((long));  __dead void     doit __P((sigset_t *));
 __dead void     done __P((int));  __dead void     done __P((int));
 void            echo __P((char));  void            echo __P((char));
 u_int           getescape __P((char *));  u_int           getescape __P((char *));
Line 130  void  lostpeer __P((int));
Line 131  void  lostpeer __P((int));
 void            mode __P((int));  void            mode __P((int));
 void            msg __P((char *));  void            msg __P((char *));
 void            oob __P((int));  void            oob __P((int));
 int             reader __P((int));  int             reader __P((sigset_t *));
 void            sendwindow __P((void));  void            sendwindow __P((void));
 void            setsignal __P((int));  void            setsignal __P((int));
   int             speed __P((int));
 void            sigwinch __P((int));  void            sigwinch __P((int));
 void            stop __P((int));  void            stop __P((int));
 __dead void     usage __P((void));  __dead void     usage __P((void));
Line 151  main(argc, argv)
Line 153  main(argc, argv)
         int argc;          int argc;
         char *argv[];          char *argv[];
 {  {
         extern char *optarg;  
         extern int optind;  
         struct passwd *pw;          struct passwd *pw;
         struct servent *sp;          struct servent *sp;
         struct termios tty;          struct termios tty;
         long omask;          sigset_t smask;
         int argoff, ch, dflag, one, uid;          int argoff, ch, dflag, one, uid;
         int i, len, len2;          int i, len, len2;
         char *host, *p, *user, term[1024] = "network";          char *host, *p, *user, term[1024] = "network";
         speed_t ospeed;          speed_t ospeed;
           struct sigaction sa;
   
         argoff = dflag = 0;          argoff = dflag = 0;
         one = 1;          one = 1;
         host = user = NULL;          host = user = NULL;
   
         if (p = rindex(argv[0], '/'))          if (p = strrchr(argv[0], '/'))
                 ++p;                  ++p;
         else          else
                 p = argv[0];                  p = argv[0];
   
         if (strcmp(p, "rlogin"))          if (strcmp(p, "rlogin") != 0)
                 host = p;                  host = p;
   
         /* handle "rlogin host flags" */          /* handle "rlogin host flags" */
Line 237  main(argc, argv)
Line 238  main(argc, argv)
         if (*argv)          if (*argv)
                 usage();                  usage();
   
         if (!(pw = getpwuid(uid = getuid()))) {          if (!(pw = getpwuid(uid = getuid())))
                 (void)fprintf(stderr, "rlogin: unknown user id.\n");                  errx(1, "unknown user id.");
                 exit(1);          /* Accept user1@host format, though "-l user2" overrides user1 */
           p = strchr(host, '@');
           if (p) {
                   *p = '\0';
                   if (!user && p > host)
                           user = host;
                   host = p + 1;
                   if (*host == '\0')
                           usage();
         }          }
         if (!user)          if (!user)
                 user = pw->pw_name;                  user = pw->pw_name;
Line 257  main(argc, argv)
Line 266  main(argc, argv)
 #endif  #endif
         if (sp == NULL)          if (sp == NULL)
                 sp = getservbyname("login", "tcp");                  sp = getservbyname("login", "tcp");
         if (sp == NULL) {          if (sp == NULL)
                 (void)fprintf(stderr, "rlogin: login/tcp: unknown service.\n");                  errx(1, "login/tcp: unknown service.");
                 exit(1);  
         }  
   
         if (p = getenv("TERM")) {          if (p = getenv("TERM")) {
                 (void)strncpy(term, p, sizeof(term) - 1);                  (void)strncpy(term, p, sizeof(term) - 1);
Line 278  main(argc, argv)
Line 285  main(argc, argv)
   
         (void)get_window_size(0, &winsize);          (void)get_window_size(0, &winsize);
   
         (void)signal(SIGPIPE, lostpeer);          sigemptyset(&sa.sa_mask);
           sa.sa_flags = SA_RESTART;
           sa.sa_handler = lostpeer;
           (void)sigaction(SIGPIPE, &sa, (struct sigaction *) 0);
         /* will use SIGUSR1 for window size hack, so hold it off */          /* will use SIGUSR1 for window size hack, so hold it off */
         omask = sigblock(sigmask(SIGURG) | sigmask(SIGUSR1));          sigemptyset(&smask);
           sigaddset(&smask, SIGURG);
           sigaddset(&smask, SIGUSR1);
           (void)sigprocmask(SIG_SETMASK, &smask, &smask);
         /*          /*
          * We set SIGURG and SIGUSR1 below so that an           * We set SIGURG and SIGUSR1 below so that an
          * incoming signal will be held pending rather than being           * incoming signal will be held pending rather than being
          * discarded. Note that these routines will be ready to get           * discarded. Note that these routines will be ready to get
          * a signal by the time that they are unblocked below.           * a signal by the time that they are unblocked below.
          */           */
         (void)signal(SIGURG, copytochild);          sa.sa_handler = copytochild;
         (void)signal(SIGUSR1, writeroob);          (void)sigaction(SIGURG, &sa, (struct sigaction *) 0);
           sa.sa_handler = writeroob;
           (void)sigaction(SIGUSR1, &sa, (struct sigaction *) 0);
   
 #ifdef KERBEROS  #ifdef KERBEROS
 try_connect:  try_connect:
Line 297  try_connect:
Line 312  try_connect:
   
                 /* Fully qualify hostname (needed for krb_realmofhost). */                  /* Fully qualify hostname (needed for krb_realmofhost). */
                 hp = gethostbyname(host);                  hp = gethostbyname(host);
                 if (hp != NULL && !(host = strdup(hp->h_name))) {                  if (hp != NULL && !(host = strdup(hp->h_name)))
                         (void)fprintf(stderr, "rlogin: %s\n",                          errx(1, "%s", strerror(ENOMEM));
                             strerror(ENOMEM));  
                         exit(1);  
                 }  
   
                 rem = KSUCCESS;                  rem = KSUCCESS;
                 errno = 0;                  errno = 0;
Line 319  try_connect:
Line 331  try_connect:
                 if (rem < 0) {                  if (rem < 0) {
                         use_kerberos = 0;                          use_kerberos = 0;
                         sp = getservbyname("login", "tcp");                          sp = getservbyname("login", "tcp");
                         if (sp == NULL) {                          if (sp == NULL)
                                 (void)fprintf(stderr,                                  errx(1, "unknown service login/tcp.");
                                     "rlogin: unknown service login/tcp.\n");  
                                 exit(1);  
                         }  
                         if (errno == ECONNREFUSED)                          if (errno == ECONNREFUSED)
                                 warning("remote host doesn't support Kerberos");                                  warning("remote host doesn't support Kerberos");
                         if (errno == ENOENT)                          if (errno == ENOENT)
Line 332  try_connect:
Line 341  try_connect:
                 }                  }
         } else {          } else {
 #ifdef CRYPT  #ifdef CRYPT
                 if (doencrypt) {                  if (doencrypt)
                         (void)fprintf(stderr,                          errx(1, "the -x flag requires Kerberos authentication.");
                             "rlogin: the -x flag requires Kerberos authentication.\n");  
                         exit(1);  
                 }  
 #endif /* CRYPT */  #endif /* CRYPT */
                 rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0);                  rem = rcmd(&host, sp->s_port, pw->pw_name, user, term, 0);
         }          }
Line 349  try_connect:
Line 355  try_connect:
   
         if (dflag &&          if (dflag &&
             setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof(one)) < 0)              setsockopt(rem, SOL_SOCKET, SO_DEBUG, &one, sizeof(one)) < 0)
                 (void)fprintf(stderr, "rlogin: setsockopt: %s.\n",                  warn("setsockopt DEBUG (ignored)");
                     strerror(errno));  
         one = IPTOS_LOWDELAY;          one = IPTOS_LOWDELAY;
         if (setsockopt(rem, IPPROTO_IP, IP_TOS, (char *)&one, sizeof(int)) < 0)          if (setsockopt(rem, IPPROTO_IP, IP_TOS, (char *)&one, sizeof(int)) < 0)
                 perror("rlogin: setsockopt TOS (ignored)");                  warn("setsockopt TOS (ignored)");
   
         (void)setuid(uid);          (void)setuid(uid);
         doit(omask);          doit(&smask);
         /*NOTREACHED*/          /*NOTREACHED*/
 }  }
   
 int child;  #if BSD >= 198810
   int
   speed(fd)
           int fd;
   {
           struct termios tt;
   
           (void)tcgetattr(fd, &tt);
   
           return ((int) cfgetispeed(&tt));
   }
   #else
   int    speeds[] = {     /* for older systems, B0 .. EXTB */
           0, 50, 75, 110,
           134, 150, 200, 300,
           600, 1200, 1800, 2400,
           4800, 9600, 19200, 38400
   };
   
   int
   speed(fd)
           int fd;
   {
           struct termios tt;
   
           (void)tcgetattr(fd, &tt);
   
           return (speeds[(int)cfgetispeed(&tt)]);
   }
   #endif
   
   pid_t child;
   struct termios deftt;
   struct termios nott;
   
 void  void
 doit(omask)  doit(smask)
         long omask;          sigset_t *smask;
 {  {
           int i;
           struct sigaction sa;
   
         (void)signal(SIGINT, SIG_IGN);          for (i = 0; i < NCCS; i++)
                   nott.c_cc[i] = _POSIX_VDISABLE;
           tcgetattr(0, &deftt);
           nott.c_cc[VSTART] = deftt.c_cc[VSTART];
           nott.c_cc[VSTOP] = deftt.c_cc[VSTOP];
           sigemptyset(&sa.sa_mask);
           sa.sa_flags = SA_RESTART;
           sa.sa_handler = SIG_IGN;
           (void)sigaction(SIGINT, &sa, (struct sigaction *) 0);
         setsignal(SIGHUP);          setsignal(SIGHUP);
         setsignal(SIGQUIT);          setsignal(SIGQUIT);
         mode(1);          mode(1);
         child = fork();          child = fork();
         if (child == -1) {          if (child == -1) {
                 (void)fprintf(stderr, "rlogin: fork: %s.\n", strerror(errno));                  warn("fork");
                 done(1);                  done(1);
         }          }
         if (child == 0) {          if (child == 0) {
                 if (reader(omask) == 0) {                  mode(1);
                   if (reader(smask) == 0) {
                         msg("connection closed.");                          msg("connection closed.");
                         exit(0);                          exit(0);
                 }                  }
Line 393  doit(omask)
Line 442  doit(omask)
          * signals to the child. We can now unblock SIGURG and SIGUSR1           * signals to the child. We can now unblock SIGURG and SIGUSR1
          * that were set above.           * that were set above.
          */           */
         (void)sigsetmask(omask);          (void)sigprocmask(SIG_SETMASK, smask, (sigset_t *) 0);
         (void)signal(SIGCHLD, catch_child);          sa.sa_handler = catch_child;
           (void)sigaction(SIGCHLD, &sa, (struct sigaction *) 0);
         writer();          writer();
         msg("closed connection.");          msg("closed connection.");
         done(0);          done(0);
Line 405  void
Line 455  void
 setsignal(sig)  setsignal(sig)
         int sig;          int sig;
 {  {
         int omask = sigblock(sigmask(sig));          struct sigaction sa;
           sigset_t sigs;
   
           sigemptyset(&sigs);
           sigaddset(&sigs, sig);
           sigprocmask(SIG_BLOCK, &sigs, &sigs);
   
           sigemptyset(&sa.sa_mask);
           sa.sa_handler = exit;
           sa.sa_flags = SA_RESTART;
           (void)sigaction(sig, &sa, &sa);
           if (sa.sa_handler == SIG_IGN)
                   (void)sigaction(sig, &sa, (struct sigaction *) 0);
   
         if (signal(sig, exit) == SIG_IGN)          (void)sigprocmask(SIG_SETMASK, &sigs, (sigset_t *) 0);
                 (void)signal(sig, SIG_IGN);  
         (void)sigsetmask(omask);  
 }  }
   
 __dead void  __dead void
 done(status)  done(status)
         int status;          int status;
 {  {
         int w, wstatus;          pid_t w;
           int wstatus;
           struct sigaction sa;
   
         mode(0);          mode(0);
         if (child > 0) {          if (child > 0) {
                 /* make sure catch_child does not snap it up */                  /* make sure catch_child does not snap it up */
                 (void)signal(SIGCHLD, SIG_DFL);                  sigemptyset(&sa.sa_mask);
                   sa.sa_handler = SIG_DFL;
                   sa.sa_flags = 0;
                   (void)sigaction(SIGCHLD, &sa, (struct sigaction *) 0);
                 if (kill(child, SIGKILL) >= 0)                  if (kill(child, SIGKILL) >= 0)
                         while ((w = wait(&wstatus)) > 0 && w != child);                          while ((w = wait(&wstatus)) > 0 && w != child)
                                   continue;
         }          }
         exit(status);          exit(status);
 }  }
Line 438  void
Line 504  void
 writeroob(signo)  writeroob(signo)
         int signo;          int signo;
 {  {
           struct sigaction sa;
   
         if (dosigwinch == 0) {          if (dosigwinch == 0) {
                 sendwindow();                  sendwindow();
                 (void)signal(SIGWINCH, sigwinch);                  sigemptyset(&sa.sa_mask);
                   sa.sa_handler = sigwinch;
                   sa.sa_flags = SA_RESTART;
                   (void)sigaction(SIGWINCH, &sa, (struct sigaction *) 0);
         }          }
         dosigwinch = 1;          dosigwinch = 1;
 }  }
Line 449  void
Line 520  void
 catch_child(signo)  catch_child(signo)
         int signo;          int signo;
 {  {
         union wait status;          int status;
         int pid;          pid_t pid;
   
         for (;;) {          for (;;) {
                 pid = wait3((int *)&status, WNOHANG|WUNTRACED, NULL);                  pid = waitpid(-1, &status, WNOHANG|WUNTRACED);
                 if (pid == 0)                  if (pid == 0)
                         return;                          return;
                 /* if the child (reader) dies, just quit */                  /* if the child (reader) dies, just quit */
                 if (pid < 0 || (pid == child && !WIFSTOPPED(status)))                  if (pid < 0 || (pid == child && !WIFSTOPPED(status)))
                         done((int)(status.w_termsig | status.w_retcode));                          done(WEXITSTATUS(status) | WTERMSIG(status));
         }          }
         /* NOTREACHED */          /* NOTREACHED */
 }  }
Line 580  void
Line 651  void
 stop(all)  stop(all)
         int all;          int all;
 {  {
           struct sigaction sa;
   
         mode(0);          mode(0);
         (void)signal(SIGCHLD, SIG_IGN);          sigemptyset(&sa.sa_mask);
           sa.sa_handler = SIG_IGN;
           sa.sa_flags = SA_RESTART;
           (void)sigaction(SIGCHLD, &sa, (struct sigaction *) 0);
         (void)kill(all ? 0 : getpid(), SIGTSTP);          (void)kill(all ? 0 : getpid(), SIGTSTP);
         (void)signal(SIGCHLD, catch_child);          sa.sa_handler = catch_child;
           (void)sigaction(SIGCHLD, &sa, (struct sigaction *) 0);
         mode(1);          mode(1);
         sigwinch(0);                    /* check for size changes */          sigwinch(0);                    /* check for size changes */
 }  }
Line 595  sigwinch(signo)
Line 672  sigwinch(signo)
         struct winsize ws;          struct winsize ws;
   
         if (dosigwinch && get_window_size(0, &ws) == 0 &&          if (dosigwinch && get_window_size(0, &ws) == 0 &&
             bcmp(&ws, &winsize, sizeof(ws))) {              memcmp(&ws, &winsize, sizeof(ws))) {
                 winsize = ws;                  winsize = ws;
                 sendwindow();                  sendwindow();
         }          }
Line 637  sendwindow()
Line 714  sendwindow()
 #define WRITING 2  #define WRITING 2
   
 jmp_buf rcvtop;  jmp_buf rcvtop;
 int ppid, rcvcnt, rcvstate;  pid_t ppid;
   int rcvcnt, rcvstate;
 char rcvbuf[8 * 1024];  char rcvbuf[8 * 1024];
   
 void  void
Line 691  oob(signo)
Line 769  oob(signo)
                 (void)tcflush(1, TCIOFLUSH);                  (void)tcflush(1, TCIOFLUSH);
                 for (;;) {                  for (;;) {
                         if (ioctl(rem, SIOCATMARK, &atmark) < 0) {                          if (ioctl(rem, SIOCATMARK, &atmark) < 0) {
                                 (void)fprintf(stderr, "rlogin: ioctl: %s.\n",                                  warn("ioctl SIOCATMARK (ignored)");
                                     strerror(errno));  
                                 break;                                  break;
                         }                          }
                         if (atmark)                          if (atmark)
Line 724  oob(signo)
Line 801  oob(signo)
   
 /* reader: read from remote: line -> 1 */  /* reader: read from remote: line -> 1 */
 int  int
 reader(omask)  reader(smask)
         int omask;          sigset_t *smask;
 {  {
         int pid, n, remaining;          pid_t pid;
           int n, remaining;
         char *bufp;          char *bufp;
           struct sigaction sa;
   
 #if BSD >= 43 || defined(SUNOS4)  #if BSD >= 43 || defined(SUNOS4)
         pid = getpid();         /* modern systems use positives for pid */          pid = getpid();         /* modern systems use positives for pid */
 #else  #else
         pid = -getpid();        /* old broken systems use negatives */          pid = -getpid();        /* old broken systems use negatives */
 #endif  #endif
         (void)signal(SIGTTOU, SIG_IGN);          sigemptyset(&sa.sa_mask);
         (void)signal(SIGURG, oob);          sa.sa_flags = SA_RESTART;
           sa.sa_handler = SIG_IGN;
           (void)sigaction(SIGTTOU, &sa, (struct sigaction *) 0);
           sa.sa_handler = oob;
           (void)sigaction(SIGURG, &sa, (struct sigaction *) 0);
         ppid = getppid();          ppid = getppid();
         (void)fcntl(rem, F_SETOWN, pid);          (void)fcntl(rem, F_SETOWN, pid);
         (void)setjmp(rcvtop);          (void)setjmp(rcvtop);
         (void)sigsetmask(omask);          (void)sigprocmask(SIG_SETMASK, smask, (sigset_t *) 0);
         bufp = rcvbuf;          bufp = rcvbuf;
         for (;;) {          for (;;) {
                 while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) {                  while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0) {
Line 770  reader(omask)
Line 853  reader(omask)
                 if (rcvcnt < 0) {                  if (rcvcnt < 0) {
                         if (errno == EINTR)                          if (errno == EINTR)
                                 continue;                                  continue;
                         (void)fprintf(stderr, "rlogin: read: %s.\n",                          warn("read");
                             strerror(errno));  
                         return (-1);                          return (-1);
                 }                  }
         }          }
Line 803  mode(f)
Line 885  mode(f)
                 }                  }
                 (void)tcsetattr(0, TCSANOW, &tty);                  (void)tcsetattr(0, TCSANOW, &tty);
                 break;                  break;
   
         default:          default:
                 return;                  return;
         }          }
Line 812  void
Line 895  void
 lostpeer(signo)  lostpeer(signo)
         int signo;          int signo;
 {  {
         (void)signal(SIGPIPE, SIG_IGN);          struct sigaction sa;
           sa.sa_flags = SA_RESTART;
           sa.sa_handler = SIG_IGN;
           (void)sigaction(SIGPIPE, &sa, (struct sigaction *)0);
         msg("\aconnection closed.");          msg("\aconnection closed.");
         done(1);          done(1);
 }  }
Line 822  void
Line 908  void
 copytochild(signo)  copytochild(signo)
         int signo;          int signo;
 {  {
   
         (void)kill(child, SIGURG);          (void)kill(child, SIGURG);
 }  }
   
Line 829  void
Line 916  void
 msg(str)  msg(str)
         char *str;          char *str;
 {  {
   
         (void)fprintf(stderr, "rlogin: %s\r\n", str);          (void)fprintf(stderr, "rlogin: %s\r\n", str);
 }  }
   
Line 861  __dead void
Line 949  __dead void
 usage()  usage()
 {  {
         (void)fprintf(stderr,          (void)fprintf(stderr,
             "usage: rlogin [ -%s]%s[-e char] [ -l username ] host\n",              "usage: rlogin [ -%s]%s[-e char] [ -l username ] [username@]host\n",
 #ifdef KERBEROS  #ifdef KERBEROS
 #ifdef CRYPT  #ifdef CRYPT
             "8EKLx", " [-k realm] ");              "8EKLx", " [-k realm] ");

Legend:
Removed from v.1.14  
changed lines
  Added in v.1.15

CVSweb <webmaster@jp.NetBSD.org>