⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rlogin.c

📁 压缩包中包含LINUX下多个命令的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
   * signals to the child. We can now unblock SIGURG and SIGUSR1   * that were set above.   */  /* Reenables SIGURG and SIUSR1.  */  sigprocmask (SIG_SETMASK, smask, (sigset_t *) 0);  setsig (SIGCHLD, catch_child);  writer ();  /* If the write returns, it means the user entered "~." on the terminal.     In this case we terminate and the server will eventually get an EOF     on its end of the network connection.  This should cause the server to     log you out on the remote system.  */  msg ("closed connection.");  done (0);}/* Enable a signal handler, unless the signal is already being ignored.   This function is called before the fork (), for SIGHUP and SIGQUIT.  *//* Trap a signal, unless it is being ignored. */voidsetsignal (int sig){  sig_t handler;  sigset_t sigs;  sigemptyset(&sigs);  sigaddset(&sigs, sig);  sigprocmask(SIG_BLOCK, &sigs, &sigs);  handler = setsig (sig, exit);  if (handler == SIG_IGN)    setsig (sig, handler);  sigprocmask(SIG_SETMASK, &sigs, (sigset_t *) 0);}/* This function is called by the parent:   (1) at the end (user terminates the client end);   (2) SIGCLD signal - the sigcld_parent () function.   (3) SIGPPE signal - the connection has dropped.   We send the child a SIGKILL signal, which it can't ignore, then   wait for it to terminate.  */voiddone (int status){  pid_t w;  int wstatus;  mode(0);  if (child > 0)    {      /* make sure catch_child does not snap it up */      setsig (SIGCHLD, SIG_DFL);      if (kill (child, SIGKILL) >= 0)	while ((w = wait (&wstatus)) > 0 && w != child)	  continue;    }  exit (status);}int dosigwinch;/* * This is called when the reader process gets the out-of-band (urgent) * request to turn on the window-changing protocol. */voidwriteroob (int signo){  (void)signo;  if (dosigwinch == 0)    {      sendwindow ();      setsig (SIGWINCH, sigwinch);    }  dosigwinch = 1;}voidcatch_child (int signo){  int status;  pid_t pid;  (void)signo;  for (;;)    {      pid = waitpid (-1, &status, WNOHANG | WUNTRACED);      if (pid == 0)	return;      /* if the child (reader) dies, just quit */      if (pid < 0 || (pid == child && !WIFSTOPPED (status)))	done (WEXITSTATUS (status) | WTERMSIG (status));    }  /* NOTREACHED */}/* * writer: write to remote: 0 -> line. * ~.				terminate * ~^Z				suspend rlogin process. * ~<delayed-suspend char>	suspend rlogin process, but leave reader alone. */voidwriter (){  register int bol, local, n;  char c;  bol = 1;			/* beginning of line */  local = 0;  for (;;)    {      n = read (STDIN_FILENO, &c, 1);      if (n <= 0)	{	  if (n < 0 && errno == EINTR)	    continue;	  break;	}      /*       * If we're at the beginning of the line and recognize a       * command character, then we echo locally.  Otherwise,       * characters are echo'd remotely.  If the command character       * is doubled, this acts as a force and local echo is       * suppressed.       */      if (bol)	{	  bol = 0;	  if (!noescape && c == escapechar)	    {	      local = 1;	      continue;	    }	} else if (local)	  {	    local = 0;	    if (c == '.' || c == deftt.c_cc[VEOF])	      {		echo (c);		break;	      }	    if (c == deftt.c_cc[VSUSP]#ifdef VDSUSP		|| c == deftt.c_cc[VDSUSP]#endif		)	      {		bol = 1;		echo (c);		stop (c);		continue;	      }	    if (c != escapechar)#ifdef ENCRYPTION#ifdef KERBEROS	      if (doencrypt)		des_write (rem, (char *)&escapechar, 1);	      else#endif#endif		write (rem, &escapechar, 1);	  }#ifdef ENCRYPTION#ifdef KERBEROS      if (doencrypt)	{	  if (des_write (rem, &c, 1) == 0)	    {	      msg ("line gone");	      break;	    }	} else#endif#endif	  if (write (rem, &c, 1) == 0)	    {	      msg ("line gone");	      break;	    }      bol = c == deftt.c_cc[VKILL] || c == deftt.c_cc[VEOF] ||	c == deftt.c_cc[VINTR] || c == deftt.c_cc[VSUSP] ||	c == '\r' || c == '\n';    }}voidecho (register char c){  register char *p;  char buf[8];  p = buf;  c &= 0177;  *p++ = escapechar;  if (c < ' ')    {      *p++ = '^';      *p++ = c + '@';    }  else if (c == 0177)    {      *p++ = '^';      *p++ = '?';    }  else    *p++ = c;  *p++ = '\r';  *p++ = '\n';  write (STDOUT_FILENO, buf, p - buf);}voidstop (char cmdc){  mode (0);  setsig (SIGCHLD, SIG_IGN);  kill (cmdc == deftt.c_cc[VSUSP] ? 0 : getpid (), SIGTSTP);  setsig (SIGCHLD, catch_child);  mode (1);  sigwinch (0);			/* check for size changes */}voidsigwinch (int signo){  struct winsize ws;  (void)signo;  if (dosigwinch && get_window_size(0, &ws) == 0      && memcmp(&ws, &winsize, sizeof ws))    {      winsize = ws;      sendwindow ();    }}/* * Send the window size to the server via the magic escape */voidsendwindow (){  struct winsize *wp;  char obuf[4 + sizeof (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);#ifdef ENCRYPTION#ifdef KERBEROS  if(doencrypt)    des_write (rem, obuf, sizeof obuf);  else#endif#endif    write (rem, obuf, sizeof obuf);}/* * reader: read from remote: line -> 1 */#define	READING	1#define	WRITING	2jmp_buf rcvtop;pid_t ppid;int rcvcnt, rcvstate;char rcvbuf[8 * 1024];voidoob (int signo){  struct termios tt;  int atmark, n, out, rcvd;  char waste[BUFSIZ], mark;  (void)signo;  out = O_RDWR;  rcvd = 0;  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 ((size_t)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;	}    }  if (mark & TIOCPKT_WINDOW)    {      /* Let server know about window size changes */      kill (ppid, SIGUSR1);    }  if (!eight && (mark & TIOCPKT_NOSTOP))    {      tcgetattr (0, &tt);      tt.c_iflag &= ~(IXON | IXOFF);      tt.c_cc[VSTOP] = _POSIX_VDISABLE;      tt.c_cc[VSTART] = _POSIX_VDISABLE;      tcsetattr (0, TCSANOW, &tt);    }  if (!eight && (mark & TIOCPKT_DOSTOP))    {      tcgetattr(0, &tt);      tt.c_iflag |= (IXON|IXOFF);      tt.c_cc[VSTOP] = deftt.c_cc[VSTOP];      tt.c_cc[VSTART] = deftt.c_cc[VSTART];      tcsetattr (0, TCSANOW, &tt);    }  if (mark & TIOCPKT_FLUSHWRITE)    {#ifdef TIOCFLUSH      ioctl (1, TIOCFLUSH, (char *)&out);#endif      for (;;)	{	  if (ioctl (rem, SIOCATMARK, &atmark) < 0)	    {	      warn ("ioctl SIOCATMARK (ignored)");	      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 */intreader (sigset_t *smask){  pid_t pid;  int n, remaining;  char *bufp;#if BSD >= 43 || defined(SUNOS4)  pid = getpid ();		/* modern systems use positives for pid */#else  pid = -getpid ();	/* old broken systems use negatives */#endif  setsig (SIGTTOU, SIG_IGN);  setsig (SIGURG, oob);  ppid = getppid ();  fcntl (rem, F_SETOWN, pid);  setjmp (rcvtop);  sigprocmask (SIG_SETMASK, smask, (sigset_t *) 0);  bufp = rcvbuf;  for (;;)    {      while ((remaining = rcvcnt - (bufp - rcvbuf)) > 0)	{	  rcvstate = WRITING;	  n = write (STDOUT_FILENO, bufp, remaining);	  if (n < 0)	    {	      if (errno != EINTR)		return -1;	      continue;	    }	  bufp += n;	}      bufp = rcvbuf;      rcvcnt = 0;      rcvstate = READING;#ifdef ENCRYPTION#ifdef KERBEROS      if (doencrypt)	rcvcnt = des_read (rem, rcvbuf, sizeof rcvbuf);      else#endif#endif	rcvcnt = read (rem, rcvbuf, sizeof rcvbuf);      if (rcvcnt == 0)	return 0;      if (rcvcnt < 0)	{	  if (errno == EINTR)	    continue;	  warn ("read");	  return -1;	}    }}voidmode (int f){  struct termios tt;  switch (f)    {    case 0:      tcsetattr (0, TCSADRAIN, &deftt);      break;    case 1:      tt = deftt;      tt.c_oflag &= ~(OPOST);      tt.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);      tt.c_iflag &= ~(ICRNL);      tt.c_cc[VMIN] = 1;      tt.c_cc[VTIME] = 0;      if (eight)	{	  tt.c_iflag &= ~(IXON | IXOFF | ISTRIP);	  tt.c_cc[VSTOP] = _POSIX_VDISABLE;	  tt.c_cc[VSTART] = _POSIX_VDISABLE;	}      tcsetattr(0, TCSADRAIN, &tt);      break;    default:      return;    }}voidlostpeer (int signo){  (void)signo;  setsig (SIGPIPE, SIG_IGN);  msg ("\007connection closed.");  done (1);}/* copy SIGURGs to the child process. */voidcopytochild (int signo){  (void)signo;  kill (child, SIGURG);}voidmsg (const char *str){  fprintf (stderr, "rlogin: %s\r\n", str);}#ifdef KERBEROS/* VARARGS */void#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__warning (const char *fmt, ...)#elsewarning (fmt, va_alist)     char *fmt;     va_dcl#endif{  va_list ap;  fprintf (stderr, "rlogin: warning, using standard rlogin: ");#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__  va_start (ap, fmt);#else  va_start (ap);#endif  vfprintf (stderr, fmt, ap);  va_end (ap);  fprintf (stderr, ".\n");}#endifvoidusage (int status){  if (status)    {      fprintf (stderr,	       "Usage: rlogin [ -%s]%s[-e char] [ -l username ] [username@]host\n",#ifdef KERBEROS# ifdef ENCRYPTION	       "8EKx", " [-k realm] "# else	       "8EK", " [-k realm] "# endif#else	       "8EL", " "#endif	       );      fprintf (stderr, "Try rlogin --help for more information.\n");    }  else    {      puts ("Usage: rlogin [OPTION] ... hostname");      puts ("Rlogin starts a terminal session on a remote host host.");      puts ("\  -8, --8-bit       allows an eight-bit input data path at all times");      puts ("\  -E, --no-escape   stops any character from being recognized as an escape\n\                    character");      puts ("\  -d, --debug       turns on socket debugging (see setsockopt(2))");      puts ("\  -e, --escape=CHAR allows user specification of the escape character,\n\                    which is ``~'' by default");  puts ("\  -l, --user USER   run as USER on the remote system");#ifdef KERBEROS      puts ("\  -K, --kerberos    turns off all Kerberos authentication");      puts ("\  -k, --realm=REALM requests rlogin to obtain tickets for the remote host in\n\                    REALM realm instead of the remote host's realm");#ifdef ENCRYPTION      puts ("\  -x, --encrypt     turns on DES encryption for all data passed via the\n\                    rlogin session");#endif#endif      puts ("\  -V, --version     display program version");      puts ("\  -h, --help        display usage instructions");      fprintf (stdout, "\nSubmit bug reports to %s.\n", PACKAGE_BUGREPORT);    }  exit (status);}/* * The following routine provides compatibility (such as it is) between older * Suns and others.  Suns have only a `ttysize', so we convert it to a winsize. */#ifdef OLDSUNintget_window_size (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;}#endifu_intgetescape (register char *p){  long val;  int len;  if ((len = strlen (p)) == 1)	/* use any single char, including '\'.  */    return ((u_int)*p);  /* otherwise, \nnn */  if (*p == '\\' && len >= 2 && len <= 4)    {      val = strtol (++p, NULL, 8);      for (;;)	{	  if (!*++p)	    return ((u_int)val);	  if (*p < '0' || *p > '8')	    break;	}    }  msg ("illegal option value -- e");  usage (1);  /* NOTREACHED */  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -