📄 remote.c
字号:
/* remote.c: Handle I/O to remote */#include "vt.h"#include <errno.h>#include <sys/uio.h>#include <sys/socket.h>#include <netinet/in.h>#include <netdb.h>#include <fcntl.h>#ifdef PROTOTYPESstatic int get_in_addr(char *, struct in_addr *);static void receive_input(Unode *rmt);#elsestatic void receive_input();#endif#ifndef FD_ZEROtypedef struct fd_set_tag { long masks[9];} DESCR_MASK;#define FD_SET(n, p) ((p)->masks[(n) / 32] |= (1 << ((n) % 32)))#define FD_CLR(n, p) ((p)->masks[(n) / 32] &= ~(1 << ((n) % 32)))#define FD_ISSET(n, p) ((p)->masks[(n) / 32] & (1 << ((n) % 32)))#define FD_ZERO(p) bzero((p), sizeof(*(p)))#elsetypedef fd_set DESCR_MASK;#endif#define INBUF_SIZE 1024extern int errno, sys_nerr;extern unsigned long inet_addr();Unode rmt_ring; /* Dummy node for remotes ring */Unode *cur_rmt = NULL; /* Remote being processed */String kin;void init_rmt(){ rmt_ring.next = rmt_ring.prev = &rmt_ring; rmt_ring.dummy = 1;}static int get_in_addr(name, addr) char *name; struct in_addr *addr;{ struct hostent *hostent; if (isdigit(*name)) { addr->s_addr = inet_addr(name); return addr->s_addr != -1; } hostent = gethostbyname(name); if (!hostent) return 0; bcopy(hostent->h_addr, (char *) addr, sizeof(struct in_addr)); return 1;}Unode *new_rmt(addr, port) char *addr; int port;{ struct sockaddr_in saddr; struct in_addr hostaddr; int fd; Unode *rmt; saddr.sin_family = AF_INET; saddr.sin_port = htons(port); if (!get_in_addr(addr, &hostaddr)) { vtc_errmsg = "Couldn't find host"; return NULL; } vtc_errmsg = NULL; bcopy(&hostaddr, &saddr.sin_addr, sizeof(struct in_addr)); fd = socket(AF_INET, SOCK_STREAM, 0); if (fd < 0) return NULL; if (connect(fd, &saddr, sizeof(struct sockaddr_in)) < 0) { close(fd); return NULL; }#ifdef FNDELAY fcntl(fd, F_SETFL, FNDELAY);#endif rmt = unalloc(); rmt->Raddr = vtstrdup(addr); rmt->Rport = port; rmt->Rfd = fd; rmt->Rbuf = New(String); *rmt->Rbuf = empty_string; rmt->Rtelnetbuf = New(String); *rmt->Rtelnetbuf = empty_string; rmt->Rwin = NULL; rmt->Rnetread = NULL; rmt->Rpromptread = NULL; rmt->Rrstack = NULL; rmt->Robj = NULL; rmt->Rback = rmt->Rbusy = rmt->Rraw = 0; rmt->Riac = rmt->Rintent = 0; rmt->Recho = 1; rmt->Rdisconnected = 0; rmt->prev = rmt_ring.prev; rmt->next = &rmt_ring; rmt_ring.prev = rmt_ring.prev->next = rmt; return rmt;}void disconnect(rmt) Unode *rmt;{ Func *func; Unode *old_rmt; int ormt_id; if (rmt->Rdisconnected) return; rmt->Rdisconnected = 1; func = find_func("disconnect_hook"); if (func && func->cmd) { old_rmt = cur_rmt; if (cur_rmt) ormt_id = cur_rmt->id; cur_rmt = rmt; run_prog(func->cmd); cur_rmt = old_rmt && ormt_id == old_rmt->id ? old_rmt : NULL; } if (rmt->Rwin) { rmt->Rwin->Wrmt = NULL; update_echo_mode(); } close(rmt->Rfd); s_free(rmt->Rbuf); Discard(rmt->Rbuf, String); rmt->prev->next = rmt->next; rmt->next->prev = rmt->prev; if (cur_rmt == rmt) cur_rmt = NULL; destroy_pointers(rmt->frefs); break_pipe(rmt->Rrstack); discard_unode(rmt);}static void receive_input(rmt) Unode *rmt;{ int count; char block[INBUF_SIZE + 1]; do count = recv(rmt->Rfd, block, INBUF_SIZE, 0); while (count == -1 && (errno == EINTR || errno == EWOULDBLOCK)); if (count <= 0) { vtc_errflag = 1; vtc_errmsg = count ? NULL : "Connection closed by foreign host"; disconnect(rmt); return; } block[count] = '\0'; s_acat(rmt->Rbuf, block); rmt->Rinbuf = 1;}int io_check(sec, usec) long sec, usec;{ struct timeval tv, *tvp; DESCR_MASK readers, except; int count, nfd, fd; Unode *rp, *next; char block[INBUF_SIZE + 1]; if (sec == -1) { tvp = NULL; } else { tv.tv_sec = sec; tv.tv_usec = usec; tvp = &tv; } FD_ZERO(&readers); FD_ZERO(&except); FD_SET(0, &readers); nfd = 1; for (rp = rmt_ring.next; !rp->dummy; rp = rp->next) { if ((rp->Rwin || rp->Rback) && !rp->Rbusy) { fd = rp->Rfd; FD_SET(fd, &readers); if (nfd <= fd) nfd = fd + 1; } } count = select(nfd, &readers, (DESCR_MASK *) NULL, &except, tvp); if (count == 0 || count == -1 && errno == EINTR) return 0; if (count == -1) operror("select", NULL); for (rp = rmt_ring.next; !rp->dummy; rp = next) { next = rp->next; if ((rp->Rwin || rp->Rback) && !rp->Rbusy) { if (FD_ISSET(rp->Rfd, &readers)) receive_input(rp); } } if (FD_ISSET(0, &readers)) { do count = read(0, block, INBUF_SIZE); while (count == -1 && errno == EINTR); s_cat(&kin, cstr_sl(block, count)); } return 1;}int transmit(rmt, cstr) Unode *rmt; Cstr cstr;{ int written; if (rmt->Rdisconnected) return -1; while (cstr.l > 0) { written = send(rmt->Rfd, cstr.s, cstr.l, 0); if (written == -1) { if (errno == EWOULDBLOCK) { sleep(1); continue; } vtc_errflag = 1; vtc_errmsg = NULL; disconnect(rmt); return -1; } cstr.s += written; cstr.l -= written; if (cstr.l) sleep(1); } return 0;}int input_waiting(fd) int fd;{ struct timeval tv; DESCR_MASK readers; tv.tv_sec = tv.tv_usec = 0; FD_ZERO(&readers); FD_SET(fd, &readers); return select(fd + 1, &readers, (DESCR_MASK *) NULL, (DESCR_MASK *) NULL, &tv);}int process_remote_text(rmt) Unode *rmt;{ int rid = rmt->id; char *s; for (s = rmt->Rbuf->c.s; *s; s++) { if (!(rmt->Rwin || rmt->Rback) || rmt->Rbusy) { s_cpy(rmt->Rbuf, cstr_sl(s, rmt->Rbuf->c.l - (s - rmt->Rbuf->c.s))); telnet_state_machine(rmt, 0); return 1; } rmt->Rinbuf = (s[1] != 0); telnet_state_machine(rmt, (unsigned char) *s); if (rmt->id != rid) return 0; } telnet_state_machine(rmt, 0); s_term(rmt->Rbuf, 0); rmt->Rinbuf = (rmt->Rbuf->c.l != 0); return 1;}void give_remote(rmt, is, isgoahead) Unode *rmt; Istr *is; int isgoahead;{ Func *func; is->refs++; if (rmt->Rrstack && !isgoahead) { resume_istr(&rmt->Rrstack, is); } else { func = (isgoahead) ? rmt->Rpromptread : rmt->Rnetread; if (func) { run_prog_istr(func->cmd, is, NULL, rmt); } else { output(rmt->Rwin, is->rs->str.c.s); if (!isgoahead) output(rmt->Rwin, "\n"); } } dec_ref_istr(is);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -