📄 misc.c
字号:
/* * Copyright (c) 1995 Danny Gasparovski. * * Please read the file COPYRIGHT for the * terms and conditions of the copyright. */#define WANT_SYS_IOCTL_H#include <slirp.h>u_int curtime, time_fasttimo, last_slowtimo, detach_time;u_int detach_wait = 600000; /* 10 minutes */#if 0int x_port = -1;int x_display = 0;int x_screen = 0;intshow_x(buff, inso) char *buff; struct socket *inso;{ if (x_port < 0) { lprint("X Redir: X not being redirected.\r\n"); } else { lprint("X Redir: In sh/bash/zsh/etc. type: DISPLAY=%s:%d.%d; export DISPLAY\r\n", inet_ntoa(our_addr), x_port, x_screen); lprint("X Redir: In csh/tcsh/etc. type: setenv DISPLAY %s:%d.%d\r\n", inet_ntoa(our_addr), x_port, x_screen); if (x_display) lprint("X Redir: Redirecting to display %d\r\n", x_display); } return CFG_OK;}/* * XXX Allow more than one X redirection? */voidredir_x(inaddr, start_port, display, screen) u_int32_t inaddr; int start_port; int display; int screen;{ int i; if (x_port >= 0) { lprint("X Redir: X already being redirected.\r\n"); show_x(0, 0); } else { for (i = 6001 + (start_port-1); i <= 6100; i++) { if (solisten(htons(i), inaddr, htons(6000 + display), 0)) { /* Success */ x_port = i - 6000; x_display = display; x_screen = screen; show_x(0, 0); return; } } lprint("X Redir: Error: Couldn't redirect a port for X. Weird.\r\n"); }}#endif#ifndef HAVE_INET_ATONintinet_aton(cp, ia) const char *cp; struct in_addr *ia;{ u_int32_t addr = inet_addr(cp); if (addr == 0xffffffff) return 0; ia->s_addr = addr; return 1;}#endif/* * Get our IP address and put it in our_addr */voidgetouraddr(){ char buff[256]; struct hostent *he = NULL; if (gethostname(buff,256) == 0) he = gethostbyname(buff); if (he) our_addr = *(struct in_addr *)he->h_addr; if (our_addr.s_addr == 0) our_addr.s_addr = loopback_addr.s_addr;}#if SIZEOF_CHAR_P == 8struct quehead_32 { u_int32_t qh_link; u_int32_t qh_rlink;};inline voidinsque_32(a, b) void *a; void *b;{ register struct quehead_32 *element = (struct quehead_32 *) a; register struct quehead_32 *head = (struct quehead_32 *) b; element->qh_link = head->qh_link; head->qh_link = (u_int32_t)element; element->qh_rlink = (u_int32_t)head; ((struct quehead_32 *)(element->qh_link))->qh_rlink = (u_int32_t)element;}inline voidremque_32(a) void *a;{ register struct quehead_32 *element = (struct quehead_32 *) a; ((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink; ((struct quehead_32 *)(element->qh_rlink))->qh_link = element->qh_link; element->qh_rlink = 0;}#endif /* SIZEOF_CHAR_P == 8 */struct quehead { struct quehead *qh_link; struct quehead *qh_rlink;};inline voidinsque(a, b) void *a, *b;{ register struct quehead *element = (struct quehead *) a; register struct quehead *head = (struct quehead *) b; element->qh_link = head->qh_link; head->qh_link = (struct quehead *)element; element->qh_rlink = (struct quehead *)head; ((struct quehead *)(element->qh_link))->qh_rlink = (struct quehead *)element;}inline voidremque(a) void *a;{ register struct quehead *element = (struct quehead *) a; ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink; ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link; element->qh_rlink = NULL; /* element->qh_link = NULL; TCP FIN1 crashes if you do this. Why ? */}/* #endif */intadd_exec(ex_ptr, do_pty, exec, addr, port) struct ex_list **ex_ptr; int do_pty; char *exec; int addr; int port;{ struct ex_list *tmp_ptr; /* First, check if the port is "bound" */ for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) { if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr) return -1; } tmp_ptr = *ex_ptr; *ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list)); (*ex_ptr)->ex_fport = port; (*ex_ptr)->ex_addr = addr; (*ex_ptr)->ex_pty = do_pty; (*ex_ptr)->ex_exec = strdup(exec); (*ex_ptr)->ex_next = tmp_ptr; return 0;}#ifndef HAVE_STRERROR/* * For systems with no strerror */extern int sys_nerr;extern char *sys_errlist[];char *strerror(error) int error;{ if (error < sys_nerr) return sys_errlist[error]; else return "Unknown error.";}#endif#ifdef _WIN32intfork_exec(so, ex, do_pty) struct socket *so; char *ex; int do_pty;{ /* not implemented */ return 0;}#elseintslirp_openpty(amaster, aslave) int *amaster, *aslave;{ register int master, slave;#ifdef HAVE_GRANTPT char *ptr; if ((master = open("/dev/ptmx", O_RDWR)) < 0 || grantpt(master) < 0 || unlockpt(master) < 0 || (ptr = ptsname(master)) == NULL) { close(master); return -1; } if ((slave = open(ptr, O_RDWR)) < 0 || ioctl(slave, I_PUSH, "ptem") < 0 || ioctl(slave, I_PUSH, "ldterm") < 0 || ioctl(slave, I_PUSH, "ttcompat") < 0) { close(master); close(slave); return -1; } *amaster = master; *aslave = slave; return 0; #else static char line[] = "/dev/ptyXX"; register const char *cp1, *cp2; for (cp1 = "pqrsPQRS"; *cp1; cp1++) { line[8] = *cp1; for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) { line[9] = *cp2; if ((master = open(line, O_RDWR, 0)) == -1) { if (errno == ENOENT) return (-1); /* out of ptys */ } else { line[5] = 't'; /* These will fail */ (void) chown(line, getuid(), 0); (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);#ifdef HAVE_REVOKE (void) revoke(line);#endif if ((slave = open(line, O_RDWR, 0)) != -1) { *amaster = master; *aslave = slave; return 0; } (void) close(master); line[5] = 'p'; } } } errno = ENOENT; /* out of ptys */ return (-1);#endif}/* * XXX This is ugly * We create and bind a socket, then fork off to another * process, which connects to this socket, after which we * exec the wanted program. If something (strange) happens, * the accept() call could block us forever. * * do_pty = 0 Fork/exec inetd style * do_pty = 1 Fork/exec using slirp.telnetd * do_ptr = 2 Fork/exec using pty */intfork_exec(so, ex, do_pty) struct socket *so; char *ex; int do_pty;{ int s; struct sockaddr_in addr; int addrlen = sizeof(addr); int opt; int master; char *argv[256];#if 0 char buff[256];#endif /* don't want to clobber the original */ char *bptr; char *curarg; int c, i, ret; DEBUG_CALL("fork_exec"); DEBUG_ARG("so = %lx", (long)so); DEBUG_ARG("ex = %lx", (long)ex); DEBUG_ARG("do_pty = %lx", (long)do_pty); if (do_pty == 2) { if (slirp_openpty(&master, &s) == -1) { lprint("Error: openpty failed: %s\n", strerror(errno)); return 0; } } else { addr.sin_family = AF_INET; addr.sin_port = 0; addr.sin_addr.s_addr = INADDR_ANY; if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 || bind(s, (struct sockaddr *)&addr, addrlen) < 0 || listen(s, 1) < 0) { lprint("Error: inet socket: %s\n", strerror(errno)); closesocket(s); return 0; } } switch(fork()) { case -1: lprint("Error: fork failed: %s\n", strerror(errno)); close(s); if (do_pty == 2) close(master); return 0; case 0: /* Set the DISPLAY */ if (do_pty == 2) { (void) close(master);#ifdef TIOCSCTTY /* XXXXX */ (void) setsid(); ioctl(s, TIOCSCTTY, (char *)NULL);#endif } else { getsockname(s, (struct sockaddr *)&addr, &addrlen); close(s); /* * Connect to the socket * XXX If any of these fail, we're in trouble! */ s = socket(AF_INET, SOCK_STREAM, 0); addr.sin_addr = loopback_addr; do { ret = connect(s, (struct sockaddr *)&addr, addrlen); } while (ret < 0 && errno == EINTR); } #if 0 if (x_port >= 0) {#ifdef HAVE_SETENV sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); setenv("DISPLAY", buff, 1);#else sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); putenv(buff);#endif }#endif dup2(s, 0); dup2(s, 1); dup2(s, 2); for (s = 3; s <= 255; s++) close(s); i = 0; bptr = strdup(ex); /* No need to free() this */ if (do_pty == 1) { /* Setup "slirp.telnetd -x" */ argv[i++] = "slirp.telnetd"; argv[i++] = "-x"; argv[i++] = bptr; } else do { /* Change the string into argv[] */ curarg = bptr; while (*bptr != ' ' && *bptr != (char)0) bptr++; c = *bptr; *bptr++ = (char)0; argv[i++] = strdup(curarg); } while (c); argv[i] = 0; execvp(argv[0], argv); /* Ooops, failed, let's tell the user why */ { char buff[256]; sprintf(buff, "Error: execvp of %s failed: %s\n", argv[0], strerror(errno)); write(2, buff, strlen(buff)+1); } close(0); close(1); close(2); /* XXX */ exit(1); default: if (do_pty == 2) { close(s); so->s = master; } else { /* * XXX this could block us... * XXX Should set a timer here, and if accept() doesn't * return after X seconds, declare it a failure * The only reason this will block forever is if socket() * of connect() fail in the child process */ do { so->s = accept(s, (struct sockaddr *)&addr, &addrlen); } while (so->s < 0 && errno == EINTR); closesocket(s); opt = 1; setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); opt = 1; setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); } fd_nonblock(so->s); /* Append the telnet options now */ if (so->so_m != 0 && do_pty == 1) { sbappend(so, so->so_m); so->so_m = 0; } return 1; }}#endif#ifndef HAVE_STRDUPchar *strdup(str) const char *str;{ char *bptr; bptr = (char *)malloc(strlen(str)+1); strcpy(bptr, str); return bptr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -