📄 rlogin.c
字号:
} completed_1(result, errno); return; } completed_1(offset, 0);}static voidrestart_rd_rem(){ size_t offset; int result, error; assert(!inprogress_rd_rem); rd_rem_offset= 0; offset= 0; while (offset < RD_REM_BUFSIZE) { result= read(rem, rd_rem_buf+offset, RD_REM_BUFSIZE-offset); if (result > 0) { offset += result; assert(offset <= RD_REM_BUFSIZE); continue; } error= errno; if (offset != 0) completed_rd_rem(offset, 0); rd_rem_offset= offset; if (result == -1 && error == EINPROGRESS) { inprogress_rd_rem= 1; return; } completed_rd_rem(result, error); return; } completed_rd_rem(offset, 0);}static voidrestart_wr_rem(){ size_t offset; int result, error; assert(!inprogress_wr_rem); if (extra_wr_rem_new != NULL && extra_wr_rem == NULL) { extra_wr_rem= extra_wr_rem_new; extra_wr_rem_size= extra_wr_rem_new_size; extra_wr_rem_offset= 0; extra_wr_rem_new= NULL; extra_wr_rem_new_size= 0; } if (extra_wr_rem != NULL) { offset= 0; while (offset < extra_wr_rem_size) { result= write(rem, extra_wr_rem+extra_wr_rem_offset+offset, extra_wr_rem_size-offset); if (result > 0) { assert (result <= extra_wr_rem_size-offset); offset += result; continue; } error= errno; if (offset != 0) completed_wr_rem(offset, 0); if (result == -1 && errno == EINPROGRESS) { inprogress_wr_rem= 1; return; } completed_wr_rem(result, errno); return; } completed_wr_rem(offset, 0); } if (wr_rem_size == 0) return; offset= 0; while (offset < wr_rem_size) { result= write(rem, rd_0_buf+wr_rem_offset+offset, wr_rem_size-offset); if (result > 0) { assert (result <= wr_rem_size-offset); offset += result; continue; } error= errno; if (offset != 0) completed_wr_rem(offset, 0); if (result == -1 && errno == EINPROGRESS) { inprogress_wr_rem= 1; return; } completed_wr_rem(result, errno); return; } completed_wr_rem(offset, 0);}static voidcompleted_0(result, error) int result; int error;{ static int bol= 0, local= 0; char *iptr, *optr; int i; u_char c; inprogress_0= 0; if (result > 0) { assert(rd_0_offset > 0); wr_rem_offset= 1; iptr= rd_0_buf+rd_0_offset; optr= rd_0_buf+wr_rem_offset; for (i= 0; i<result; iptr++, i++) { c= *iptr; if (bol) { bol= 0; if (!noescape && c == escapechar) { local= 1; continue; } } else if (local) { local= 0; if (c == '.' || (c != _POSIX_VDISABLE && c == defattr.c_cc[VEOF])) { echo(c); finish(); /* NOTREACHED */ } if (c == '!') { subshell(); continue; } if (c != escapechar) { if (optr < iptr) { *(optr++)= escapechar; } else { assert(optr == iptr); assert(iptr == rd_0_buf+ rd_0_offset); assert(rd_0_offset > 0); wr_rem_offset--; optr[-1]= escapechar; } } } *(optr++)= c; bol= (c != _POSIX_VDISABLE) && (c == defattr.c_cc[VKILL] || c == defattr.c_cc[VEOF] || c == defattr.c_cc[VINTR] || c == defattr.c_cc[VSUSP] || c == '\r' || c == '\n'); } wr_rem_size += optr-rd_0_buf-wr_rem_offset; if (wr_rem_size != 0) { more2read_0= 0; more2write_rem= 1; } return; } fprintf(stderr, "completed_0: %d, %d\n", result, error); abort();}static voidcompleted_1(result, error) int result; int error;{ inprogress_1= 0; if (result > 0) { if (extra_1 != NULL) { assert (result <= extra_1_size); extra_1_size -= result; extra_1_offset += result; if (extra_1_size == 0) { more2write_1= 0; more2read_rem= 1; free(extra_1); extra_1= NULL; } return; } assert (result <= wr_1_size); wr_1_size -= result; wr_1_offset += result; if (wr_1_size == 0) { more2write_1= 0; more2read_rem= 1; } return; } fprintf(stderr, "completed_1: %d, %d\n", result, error); abort();}static voidcompleted_rd_rem(result, error) int result; int error;{ nwio_tcpopt_t tcpopt; char *new_buf; size_t keep_size; u_char urg_byte; int i; inprogress_rd_rem= 0; if (result > 0) { if (rd_rem_urg) {#if DEBUGfprintf(stderr, "\n\r%d urg bytes\n\r", result);#endif if (urg_1_size > MAX_EXTRA_1_NEW_SIZE) { keep_size= MAX_EXTRA_1_NEW_SIZE/2; memmove(urg_1, urg_1+urg_1_size-keep_size, keep_size); urg_1_size= keep_size; } new_buf= realloc(urg_1, urg_1_size+result); if (new_buf == NULL) { fprintf(stderr, "rlogin: warning realloc %d failed\n", urg_1_size+result); return; } memcpy(new_buf+urg_1_size, rd_rem_buf+rd_rem_offset, result); urg_1= new_buf; urg_1_size += result; return; } more2read_rem= 0; more2write_1= 1; wr_1_size= result; wr_1_offset= rd_rem_offset; return; } if (result == -1 && error == EURG) {#if DEBUGfprintf(stderr, "\n\rEURG\n\r");#endif rd_rem_urg= 1; tcpopt.nwto_flags= NWTO_RCV_URG; result= ioctl(rem, NWIOSTCPOPT, &tcpopt); if (result == -1) { fprintf(stderr, "rlogin: NWIOSTCPOPT on %d failed (%s)\n", rem, strerror(errno)); exit(1); } return; } if (result == -1 && error == ENOURG) {#if DEBUGfprintf(stderr, "\n\rENOURG\n\r");#endif rd_rem_urg= 0; tcpopt.nwto_flags= NWTO_RCV_NOTURG; result= ioctl(rem, NWIOSTCPOPT, &tcpopt); if (result == -1) { fprintf(stderr, "rlogin: NWIOSTCPOPT on %d failed (%s)\n", rem, strerror(errno)); exit(1); } if (urg_1_size != 0) { urg_byte= urg_1[urg_1_size-1]; urg_1_size--; do_urg(urg_byte); if (urg_1_size == 0) return; if (extra_1_new_size + urg_1_size > MAX_EXTRA_1_NEW_SIZE) { extra_1_new_size= 0; free(extra_1_new); extra_1_new= NULL; } if (extra_1_new_size != 0) { new_buf= realloc(extra_1_new, extra_1_new_size+urg_1_size); if (new_buf == 0) { extra_1_new_size= 0; free(extra_1_new); extra_1_new= NULL; } else { extra_1_new= new_buf; memcpy(extra_1_new+extra_1_new_size, urg_1, urg_1_size); extra_1_new_size += urg_1_size; urg_1_size= 0; free(urg_1); urg_1= NULL; } } if (extra_1_new_size == 0) { extra_1_new_size= urg_1_size; extra_1_new= urg_1; urg_1_size= 0; urg_1= NULL; } more2read_rem= 0; more2write_1= 1; } return; } if (result == -1 && error == EINTR) { /* Never mind. */ return; } if (result == 0) { msg("connection closed."); done(0); } fprintf(stderr, "completed_rd_rem: %d, %d\n", result, error); abort();}static voidcompleted_wr_rem(result, error) int result; int error;{ inprogress_wr_rem= 0; if (result > 0) { if (extra_wr_rem != NULL) { assert (result <= extra_wr_rem_size); extra_wr_rem_size -= result; extra_wr_rem_offset += result; if (extra_wr_rem_size == 0) { free(extra_wr_rem); extra_wr_rem= NULL; if (wr_rem_size == 0) { more2write_rem= 0; more2read_0= 1; } } return; } assert (result <= wr_rem_size); wr_rem_size -= result; wr_rem_offset += result; if (wr_rem_size == 0) { more2write_rem= 0; more2read_0= 1; } return; } fprintf(stderr, "completed_wr_rem: %d, %d\n", result, error); abort();}static voiddo_urg(urg_byte) int urg_byte;{#if DEBUG fprintf(stderr, "rlogin: warning got urg_byte 0x%x\r\n", urg_byte);#endif if (urg_byte & TIOCPKT_WINDOW) { if (dosigwinch == 0) { sendwindow(); signal(SIGWINCH, sigwinch); } dosigwinch= 1; }}static voidecho(c) int c;{ u_char c1; char *new_buf; new_buf= realloc(extra_1_new, extra_1_new_size+6); if (new_buf == NULL) return; extra_1_new= new_buf; new_buf= extra_1_new+extra_1_new_size; c1= escapechar; if (c1 < ' ') { *new_buf++= '^'; *new_buf++= c1 + '@'; } else if (c1 == 0x7f) { *new_buf++= '^'; *new_buf++= '?'; } else *new_buf++= c1; if (c < ' ') { *new_buf++= '^'; *new_buf++= c + '@'; } else if (c == 0x7f) { *new_buf++= '^'; *new_buf++= '?'; } else *new_buf++= c; *new_buf++= '\r'; *new_buf++= '\n'; extra_1_new_size= new_buf-extra_1_new; more2write_1= 1;}static voidfinish(){ done(0);}static char cmdbuf[256];static voidsubshell(){ /* Start a subshell. Based on the first character of the command, * the tcp connection will be present at fd 3 ('+'), or at * fd 0 and fd 1 ('=') */ int r, pid, stat, len; char *shell, *cmd; /* cancel the reads and writes that are in progress. */ if (inprogress_0) { r= fcancel(0, ASIO_READ); if (r != 0) abort(); } if (inprogress_1) { r= fcancel(1, ASIO_WRITE); if (r != 0) abort(); } if (inprogress_rd_rem) { r= fcancel(rem, ASIO_READ); if (r != 0) abort(); } if (inprogress_wr_rem) { r= fcancel(rem, ASIO_WRITE); if (r != 0) abort(); } mode(0); pid= fork(); if (pid == -1) abort(); if (pid != 0) { r= waitpid(pid, &stat, 0); if (r != pid) abort();#if DEBUG fprintf(stderr, "stat: 0x%x\n", stat);#endif mode(1); return; } (void)signal(SIGINT, SIG_DFL); shell= getenv("SHELL"); if (shell == NULL) shell= "/bin/sh"; printf("~!\ncommand [%s]: ", shell); cmd= fgets(cmdbuf, sizeof(cmdbuf), stdin); if (cmd == NULL) exit(0);#if DEBUG printf("got command '%s'\n", cmd);#endif /* Strip the trailing newline */ len= strlen(cmd); if (len > 0 && cmd[len-1] == '\n') cmd[len-1]= '\0'; else printf("\n"); /* Skip leading white space */ while (*cmd != '\0' && isspace(*cmd)) cmd++; if (*cmd == '+') { if (rem != 3) { dup2(rem, 3); close(rem); } cmd++; } else if (*cmd == '=') { dup2(rem, 0); dup2(rem, 1); close(rem); cmd++; } else close(rem); if (*cmd == '\0') { r= execl(shell, shell, NULL); } else { r= execl("/bin/sh", "sh", "-c", cmd, NULL); } printf("exec failed: %d, %d\n", r, errno); exit(0);}#endif /* __minix_vmd */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -