📄 rlogin.c
字号:
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 */}RETSIGTYPE sigwinch (int signo ARG_UNUSED){ struct winsize ws; 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#elif defined(SHISHI) if(doencrypt) writeenc (handle, rem, obuf, sizeof obuf, &wlen, &iv2, key, 2); 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];RETSIGTYPEoob (int signo ARG_UNUSED){ char mark; struct termios tt; int atmark, n, out, rcvd; char waste[BUFSIZ]; out = O_RDWR; rcvd = 0; #ifndef SHISHI 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; } }#endif 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) { error (0, errno, "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 (;;) {#ifdef SHISHI if ((rcvcnt >= 5) && (bufp[0] == '\377') && (bufp[1] == '\377')) if ((bufp[2] == 'o') && (bufp[3] == 'o')) { oob (1); bufp += 5; }#endif 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#elif defined(SHISHI) if (doencrypt) readenc (handle, rem, rcvbuf, &rcvcnt, &iv1, key, 2); else#endif#endif rcvcnt = read (rem, rcvbuf, sizeof rcvbuf); if (rcvcnt == 0) return 0; if (rcvcnt < 0) { if (errno == EINTR) continue; error (0, errno, "read"); return -1; } }}voidmode (int f){ struct termios tt; switch (f) { case 0: /* remember whether IXON is set, set it can be restore at mode(1) */ tcgetattr (0, &ixon_state); 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; } if ((ixon_state.c_iflag & IXON) && ! eight) tt.c_iflag |= IXON; else tt.c_iflag &= ~IXON; tcsetattr(0, TCSADRAIN, &tt); break; default: return; }}RETSIGTYPElostpeer (int signo ARG_UNUSED){ setsig (SIGPIPE, SIG_IGN); msg ("\007connection closed."); done (1);}/* copy SIGURGs to the child process. */RETSIGTYPEcopytochild (int signo ARG_UNUSED){ kill (child, SIGURG);}voidmsg (const char *str){ fprintf (stderr, "rlogin: %s\r\n", str);}#if defined(KERBEROS) || defined(SHISHI)/* 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",#if defined(KERBEROS) || defined(SHISHI)# 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");#if defined(KERBEROS) || defined(SHISHI) 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 + -