📄 rlogin.c
字号:
* ~^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 == deftc.t_eofc) { echo(c); break; } if (c == defltc.t_suspc || c == defltc.t_dsuspc) { bol = 1; echo(c); stop(c); continue; } if (c != escapechar)#ifdef CRYPT#ifdef KERBEROS if (doencrypt) (void)des_write(rem, (char *)&escapechar, 1); else#endif#endif (void)write(rem, &escapechar, 1); }#ifdef CRYPT#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 == defkill || c == deftc.t_eofc || c == deftc.t_intrc || c == defltc.t_suspc || c == '\r' || c == '\n'; }}void#if __STDC__echo(register char c)#elseecho(c) register char c;#endif{ 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'; (void)write(STDOUT_FILENO, buf, p - buf);}void#if __STDC__stop(char cmdc)#elsestop(cmdc) char cmdc;#endif{ mode(0); (void)signal(SIGCHLD, SIG_IGN); (void)kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP); (void)signal(SIGCHLD, catch_child); mode(1); sigwinch(0); /* check for size changes */}voidsigwinch(signo) int signo;{ struct winsize ws; if (dosigwinch && get_window_size(0, &ws) == 0 && bcmp(&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 CRYPT#ifdef KERBEROS if(doencrypt) (void)des_write(rem, obuf, sizeof(obuf)); else#endif#endif (void)write(rem, obuf, sizeof(obuf));}/* * reader: read from remote: line -> 1 */#define READING 1#define WRITING 2jmp_buf rcvtop;int ppid, rcvcnt, rcvstate;char rcvbuf[8 * 1024];voidoob(signo) int signo;{ struct sgttyb sb; int atmark, n, out, rcvd; char waste[BUFSIZ], mark; 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 (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 */ (void)kill(ppid, SIGUSR1); } if (!eight && (mark & TIOCPKT_NOSTOP)) { (void)ioctl(0, TIOCGETP, (char *)&sb); sb.sg_flags &= ~CBREAK; sb.sg_flags |= RAW; (void)ioctl(0, TIOCSETN, (char *)&sb); notc.t_stopc = -1; notc.t_startc = -1; (void)ioctl(0, TIOCSETC, (char *)¬c); } if (!eight && (mark & TIOCPKT_DOSTOP)) { (void)ioctl(0, TIOCGETP, (char *)&sb); sb.sg_flags &= ~RAW; sb.sg_flags |= CBREAK; (void)ioctl(0, TIOCSETN, (char *)&sb); notc.t_stopc = deftc.t_stopc; notc.t_startc = deftc.t_startc; (void)ioctl(0, TIOCSETC, (char *)¬c); } if (mark & TIOCPKT_FLUSHWRITE) { (void)ioctl(1, TIOCFLUSH, (char *)&out); for (;;) { if (ioctl(rem, SIOCATMARK, &atmark) < 0) { (void)fprintf(stderr, "rlogin: ioctl: %s.\n", strerror(errno)); 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(omask) int omask;{ int pid, 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 (void)signal(SIGTTOU, SIG_IGN); (void)signal(SIGURG, oob); ppid = getppid(); (void)fcntl(rem, F_SETOWN, pid); (void)setjmp(rcvtop); (void)sigsetmask(omask); 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 CRYPT#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; (void)fprintf(stderr, "rlogin: read: %s.\n", strerror(errno)); return (-1); } }}voidmode(f) int f;{ struct ltchars *ltc; struct sgttyb sb; struct tchars *tc; int lflags; (void)ioctl(0, TIOCGETP, (char *)&sb); (void)ioctl(0, TIOCLGET, (char *)&lflags); switch(f) { case 0: sb.sg_flags &= ~(CBREAK|RAW|TBDELAY); sb.sg_flags |= defflags|tabflag; tc = &deftc; ltc = &defltc; sb.sg_kill = defkill; sb.sg_erase = deferase; lflags = deflflags; break; case 1: sb.sg_flags |= (eight ? RAW : CBREAK); sb.sg_flags &= ~defflags; /* preserve tab delays, but turn off XTABS */ if ((sb.sg_flags & TBDELAY) == XTABS) sb.sg_flags &= ~TBDELAY; tc = ¬c; ltc = &noltc; sb.sg_kill = sb.sg_erase = -1; if (litout) lflags |= LLITOUT; break; default: return; } (void)ioctl(0, TIOCSLTC, (char *)ltc); (void)ioctl(0, TIOCSETC, (char *)tc); (void)ioctl(0, TIOCSETN, (char *)&sb); (void)ioctl(0, TIOCLSET, (char *)&lflags);}voidlostpeer(signo) int signo;{ (void)signal(SIGPIPE, SIG_IGN); msg("\007connection closed."); done(1);}/* copy SIGURGs to the child process. */voidcopytochild(signo) int signo;{ (void)kill(child, SIGURG);}voidmsg(str) char *str;{ (void)fprintf(stderr, "rlogin: %s\r\n", str);}#ifdef KERBEROS/* VARARGS */void#if __STDC__warning(const char *fmt, ...)#elsewarning(fmt, va_alist) char *fmt; va_dcl#endif{ va_list ap; (void)fprintf(stderr, "rlogin: warning, using standard rlogin: ");#ifdef __STDC__ va_start(ap, fmt);#else va_start(ap);#endif vfprintf(stderr, fmt, ap); va_end(ap); (void)fprintf(stderr, ".\n");}#endif__dead voidusage(){ (void)fprintf(stderr, "usage: rlogin [ -%s]%s[-e char] [ -l username ] host\n",#ifdef KERBEROS#ifdef CRYPT "8EKLx", " [-k realm] ");#else "8EKL", " [-k realm] ");#endif#else "8EL", " ");#endif exit(1);}/* * 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(fd, wp) 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(p) 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(); /* NOTREACHED */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -