📄 rlogin.c
字号:
#if !__minix_vmdstatic voidcatch_child(sig) int sig;{ int status; int pid; 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(WTERMSIG(status) | WEXITSTATUS(status)); } /* NOTREACHED */}#endif#if !__minix_vmd/* * writer: write to remote: 0 -> line. * ~. terminate * ~^Z suspend rlogin process. * ~<delayed-suspend char> suspend rlogin process, but leave reader alone. */static voidwriter(){ register int bol, local, n; u_char ch; int c; bol = 1; /* beginning of line */ local = 0; for (;;) { n = read(STDIN_FILENO, &ch, 1); if (n <= 0) { if (n < 0 && errno == EINTR) continue; break; } c = ch; /* * 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 == defattr.c_cc[VEOF]) { echo(c); break; }#if !__minix if (c == defattr.c_cc[VSUSP]) { bol = 1; echo(c); stop(c); continue; }#endif if (c != escapechar)#ifdef CRYPT#ifdef KERBEROS if (doencrypt) (void)des_write(rem, &escapechar, 1); else#endif#endif (void)write(rem, &escapechar, 1); } ch = c;#ifdef CRYPT#ifdef KERBEROS if (doencrypt) { if (des_write(rem, &ch, 1) == 0) { msg("line gone"); break; } } else#endif#endif if (write(rem, &ch, 1) == 0) { msg("line gone"); break; } bol = c == defattr.c_cc[VKILL] || c == defattr.c_cc[VEOF] || c == defattr.c_cc[VINTR] || c == defattr.c_cc[VSUSP] || c == '\r' || c == '\n'; }}#endif#if !__minix_vmdstatic voidecho(c)int 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'; (void)write(STDOUT_FILENO, buf, p - buf);}#endif#if !__minixstop(cmdc) char cmdc;{ mode(0); (void)signal(SIGCHLD, SIG_IGN); (void)kill(cmdc == defltc.t_suspc ? 0 : getpid(), SIGTSTP); (void)signal(SIGCHLD, catch_child); mode(1); sigwinch(); /* check for size changes */}#endif#if !__minix || __minix_vmdstatic voidsigwinch(sig) int sig;{ struct winsize ws;#if __minix signal(SIGWINCH, sigwinch);#endif if (dosigwinch && get_window_size(0, &ws) == 0 && memcmp(&ws, &winsize, sizeof(ws))) { winsize = ws; mustsendwindow= 1; }}/* * Send the window size to the server via the magic escape */static voidsendwindow(){ struct winsize *wp; char *obuf, *new_buf; new_buf= realloc(extra_wr_rem_new, extra_wr_rem_new_size+4+sizeof(*wp)); if (new_buf == 0) return; extra_wr_rem_new= new_buf; obuf= new_buf+extra_wr_rem_new_size; extra_wr_rem_new_size += 4+sizeof(*wp); more2read_0= 0; more2write_rem= 1; 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);}#endif /* !__minix || __minix_vmd */#if !__minix_vmd/* * reader: read from remote: line -> 1 */#define READING 1#define WRITING 2int rcvcnt, rcvstate;char rcvbuf[8 * 1024];static intreader(){ int pid = -getpid(); int n, remaining; char *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));#if __minix_vmd if (errno == EURG) { nwio_tcpopt_t tcpopt; tcpopt.nwto_flags= NWTO_RCV_URG; if (ioctl(rem, NWIOSTCPOPT, &tcpopt) == -1) { fprintf(stderr, "rlogin: trouble with urgent data: %s\n", strerror(errno)); return(-1); } continue; }#endif return(-1); } }}#endif /* !__minix_vmd */static voidmode(f) int f;{ struct termios *sb; switch(f) { case 0: sb= &defattr; break; case 1: sb= &rawattr; break; default: return; } (void)tcsetattr(0, TCSAFLUSH, sb);}static voidlostpeer(sig)int sig;{ (void)signal(SIGPIPE, SIG_IGN); msg("\007connection closed."); done(1);}static voidmsg(str) char *str;{ (void)fprintf(stderr, "rlogin: %s\r\n", str);}#ifdef KERBEROS/* VARARGS */warning(va_alist)va_dcl{ va_list ap; char *fmt; (void)fprintf(stderr, "rlogin: warning, using standard rlogin: "); va_start(ap); fmt = va_arg(ap, char *); vfprintf(stderr, fmt, ap); va_end(ap); (void)fprintf(stderr, ".\n");}#endifstatic voidusage(){ (void)fprintf(stderr, "Usage: rlogin [-%s]%s[-e char] [-l username] host\n",#ifdef KERBEROS#ifdef CRYPT "8ELx", " [-k realm] ");#else "8EL", " [-k realm] ");#endif#else "8EL", " ");#endif exit(1);}/* * The following routine provides compatibility (such as it is) between 4.2BSD * Suns and others. Suns have only a `ttysize', so we convert it to a winsize. */#ifdef sunget_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);}#endifstatic u_chargetescape(p) register char *p;{ long val; int len; if ((len = strlen(p)) == 1) /* use any single char, including '\' */ return((u_char)*p); /* otherwise, \nnn */ if (*p == '\\' && len >= 2 && len <= 4) { val = strtol(++p, (char **)NULL, 8); for (;;) { if (!*++p) return((u_char)val); if (*p < '0' || *p > '8') break; } } msg("illegal option value -- e"); usage(); /* NOTREACHED */}static char *speeds2str(speed) speed_t speed;{ int i; for (i= 0; speeds[i].name != NULL && speeds[i].speed != speed; i++) { if (speeds[i].speed == speed) return speeds[i].name; } return "unknown";}#if __minix_vmdstatic void mark_async(fd) int fd;{ int result; int v; result= fcntl(fd, F_GETFD); if (result == -1) { fprintf(stderr, "rlogin: mark_async: fcntl(%d, GETFD) failed (%s)\n", fd, strerror(errno)); exit(1); } v= result | FD_ASYNCHIO; result= fcntl(fd, F_SETFD, v); if (result == -1) { fprintf(stderr, "rlogin: mark_async: fcntl(%d, SETFD, %d) failed (%s)\n", fd, v, strerror(errno)); exit(1); }}#define RD_0_BUFSIZE 256char rd_0_buf[RD_0_BUFSIZE];size_t rd_0_offset;static voidinit_0(){ more2read_0= 1; inprogress_0= 0; rd_0_offset= 0;}size_t wr_1_size;size_t wr_1_offset;char *urg_1;size_t urg_1_size;char *extra_1;size_t extra_1_size;size_t extra_1_offset;char *extra_1_new;size_t extra_1_new_size;#define MAX_EXTRA_1_NEW_SIZE (16*1024)static voidinit_1(){ more2write_1= 0; inprogress_1= 0; wr_1_size= 0; wr_1_offset= 0; urg_1= NULL; urg_1_size= 0; extra_1= NULL; extra_1_size= 0; extra_1_offset= 0; extra_1_new= NULL; extra_1_new_size= 0;}#define RD_REM_BUFSIZE (8*1024)char rd_rem_buf[RD_REM_BUFSIZE];size_t rd_rem_offset;int rd_rem_urg;static void init_rd_rem(){ more2read_rem= 1; inprogress_rd_rem= 0; rd_rem_offset= 0; rd_rem_urg= 0;}static void init_wr_rem(){ more2write_rem= 0; inprogress_wr_rem= 0; wr_rem_size= 0; wr_rem_offset= 0; extra_wr_rem_size= 0; extra_wr_rem_offset= 0; extra_wr_rem= NULL; extra_wr_rem_new_size= 0; extra_wr_rem_new= NULL;}static voidrestart_0(){ size_t offset; int result, error; assert(!inprogress_0); rd_0_offset= 1; offset= 0; while (offset < RD_0_BUFSIZE) { result= read(0, rd_0_buf+rd_0_offset+offset, RD_0_BUFSIZE-rd_0_offset-offset); if (result > 0) { offset += result; assert(rd_0_offset+offset <= RD_0_BUFSIZE); continue; } error= errno; if (offset != 0) completed_0(offset, 0); rd_0_offset += offset; if (result == -1 && error == EINPROGRESS) { inprogress_0= 1; return; } completed_0(result, error); return; } completed_0(offset, 0);}static void restart_1(){ size_t offset; int result, error; assert(!inprogress_1); while (extra_1 != NULL || extra_1_new != NULL) { if (extra_1 == NULL) { extra_1= extra_1_new; extra_1_new= NULL; extra_1_size= extra_1_new_size; extra_1_new_size= 0; extra_1_offset= 0; } offset= 0;#if DEBUG if (extra_1_size == 0) fprintf(stderr, "restart_1: extra_1_size= 0\n");#endif while (offset < extra_1_size) { result= write(1, extra_1+extra_1_offset+offset, extra_1_size-offset); if (result > 0) { assert (result <= extra_1_size-offset); offset += result; continue; } error= errno; if (offset != 0) completed_1(offset, 0); if (result == -1 && errno == EINPROGRESS) { inprogress_1= 1; return; } completed_1(result, errno); return; } completed_1(offset, 0); } offset= 0; if (wr_1_size == 0) { more2write_1= 0; more2read_rem= 1; return; } while (offset < wr_1_size) { result= write(1, rd_rem_buf+wr_1_offset+offset, wr_1_size-offset); if (result > 0) { assert (result <= wr_1_size-offset); offset += result; continue; } error= errno; if (offset != 0) completed_1(offset, 0); if (result == -1 && errno == EINPROGRESS) { inprogress_1= 1; return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -