15d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 25d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Copyright (c) 1995 Danny Gasparovski. 35d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 45d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Please read the file COPYRIGHT for the 55d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * terms and conditions of the copyright. 65d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 75d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 85d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include <slirp.h> 95d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneru_int curtime, time_fasttimo, last_slowtimo; 115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0 135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint x_port = -1; 145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint x_display = 0; 155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint x_screen = 0; 165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint 185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnershow_x(buff, inso) 195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *buff; 205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct socket *inso; 215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (x_port < 0) { 235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("X Redir: X not being redirected.\r\n"); 245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("X Redir: In sh/bash/zsh/etc. type: DISPLAY=%s:%d.%d; export DISPLAY\r\n", 265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner inet_ntoa(our_addr), x_port, x_screen); 275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("X Redir: In csh/tcsh/etc. type: setenv DISPLAY %s:%d.%d\r\n", 285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner inet_ntoa(our_addr), x_port, x_screen); 295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (x_display) 305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("X Redir: Redirecting to display %d\r\n", x_display); 315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return CFG_OK; 345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * XXX Allow more than one X redirection? 395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid 415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerredir_x(inaddr, start_port, display, screen) 425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner u_int32_t inaddr; 435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int start_port; 445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int display; 455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int screen; 465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int i; 485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (x_port >= 0) { 505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("X Redir: X already being redirected.\r\n"); 515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner show_x(0, 0); 525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (i = 6001 + (start_port-1); i <= 6100; i++) { 545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (solisten(htons(i), inaddr, htons(6000 + display), 0)) { 555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Success */ 565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner x_port = i - 6000; 575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner x_display = display; 585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner x_screen = screen; 595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner show_x(0, 0); 605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return; 615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("X Redir: Error: Couldn't redirect a port for X. Weird.\r\n"); 645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Get our IP address and put it in our_addr 705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid 725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnergetouraddr(void) 735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char buff[256]; 755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct hostent *he = NULL; 765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (gethostname(buff,256) == 0) 785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner he = gethostbyname(buff); 795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (he) 805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner our_addr = *(struct in_addr *)he->h_addr; 815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (our_addr.s_addr == 0) 825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner our_addr.s_addr = loopback_addr.s_addr; 835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstruct quehead { 865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct quehead *qh_link; 875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct quehead *qh_rlink; 885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}; 895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerinline void 915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerinsque(void *a, void *b) 925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner register struct quehead *element = (struct quehead *) a; 945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner register struct quehead *head = (struct quehead *) b; 955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner element->qh_link = head->qh_link; 965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner head->qh_link = (struct quehead *)element; 975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner element->qh_rlink = (struct quehead *)head; 985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ((struct quehead *)(element->qh_link))->qh_rlink 995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner = (struct quehead *)element; 1005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 1015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerinline void 1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerremque(void *a) 1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 1055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner register struct quehead *element = (struct quehead *) a; 1065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink; 1075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link; 1085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner element->qh_rlink = NULL; 1095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* element->qh_link = NULL; TCP FIN1 crashes if you do this. Why ? */ 1105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 1115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* #endif */ 1135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint 1165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneradd_exec(struct ex_list **ex_ptr, int do_pty, char *exec, int addr, int port) 1175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 1185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct ex_list *tmp_ptr; 1195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* First, check if the port is "bound" */ 1215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) { 1225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr) 1235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 1255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tmp_ptr = *ex_ptr; 1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list)); 1285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (*ex_ptr)->ex_fport = port; 1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (*ex_ptr)->ex_addr = addr; 1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (*ex_ptr)->ex_pty = do_pty; 1315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (*ex_ptr)->ex_exec = (do_pty == 3) ? exec : strdup(exec); 1325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (*ex_ptr)->ex_next = tmp_ptr; 1335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 1345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 1355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef HAVE_STRERROR 1375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 1395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * For systems with no strerror 1405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerextern int sys_nerr; 1435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerextern char *sys_errlist[]; 1445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar * 1465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstrerror(error) 1475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int error; 1485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 1495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (error < sys_nerr) 1505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return sys_errlist[error]; 1515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else 1525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return "Unknown error."; 1535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 1545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32 1595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint 1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfork_exec(struct socket *so, const char *ex, int do_pty) 1625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 1635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* not implemented */ 1645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 1655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 1665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_QEMU 1705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint 1715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerslirp_openpty(amaster, aslave) 1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int *amaster, *aslave; 1735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 1745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner register int master, slave; 1755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAVE_GRANTPT 1775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *ptr; 1785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((master = open("/dev/ptmx", O_RDWR)) < 0 || 1805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner grantpt(master) < 0 || 1815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner unlockpt(master) < 0 || 1825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (ptr = ptsname(master)) == NULL) { 1835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(master); 1845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 1855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 1865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((slave = open(ptr, O_RDWR)) < 0 || 1885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ioctl(slave, I_PUSH, "ptem") < 0 || 1895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ioctl(slave, I_PUSH, "ldterm") < 0 || 1905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ioctl(slave, I_PUSH, "ttcompat") < 0) { 1915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(master); 1925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(slave); 1935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return -1; 1945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 1955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 1965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *amaster = master; 1975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *aslave = slave; 1985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 1995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 2015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner static char line[] = "/dev/ptyXX"; 2035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner register const char *cp1, *cp2; 2045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (cp1 = "pqrsPQRS"; *cp1; cp1++) { 2065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner line[8] = *cp1; 2075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) { 2085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner line[9] = *cp2; 2095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((master = open(line, O_RDWR, 0)) == -1) { 2105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (errno == ENOENT) 2115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return (-1); /* out of ptys */ 2125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 2135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner line[5] = 't'; 2145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* These will fail */ 2155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (void) chown(line, getuid(), 0); 2165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP); 2175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAVE_REVOKE 2185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (void) revoke(line); 2195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 2205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((slave = open(line, O_RDWR, 0)) != -1) { 2215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *amaster = master; 2225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *aslave = slave; 2235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 2245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (void) close(master); 2265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner line[5] = 'p'; 2275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner errno = ENOENT; /* out of ptys */ 2315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return (-1); 2325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 2345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 2355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 2375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * XXX This is ugly 2385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * We create and bind a socket, then fork off to another 2395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * process, which connects to this socket, after which we 2405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * exec the wanted program. If something (strange) happens, 2415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * the accept() call could block us forever. 2425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * 2435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * do_pty = 0 Fork/exec inetd style 2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * do_pty = 1 Fork/exec using slirp.telnetd 2455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * do_ptr = 2 Fork/exec using pty 2465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 2475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint 2485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfork_exec(struct socket *so, const char *ex, int do_pty) 2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 2505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int s; 2515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct sockaddr_in addr; 2525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner socklen_t addrlen = sizeof(addr); 2535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int opt; 2545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int master = -1; 2555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const char *argv[256]; 2565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0 2575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char buff[256]; 2585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 2595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* don't want to clobber the original */ 2605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *bptr; 2615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const char *curarg; 2625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int c, i, ret; 2635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner DEBUG_CALL("fork_exec"); 2655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner DEBUG_ARG("so = %lx", (long)so); 2665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner DEBUG_ARG("ex = %lx", (long)ex); 2675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner DEBUG_ARG("do_pty = %lx", (long)do_pty); 2685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (do_pty == 2) { 2705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0 2715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (slirp_openpty(&master, &s) == -1) { 2725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("Error: openpty failed: %s\n", strerror(errno)); 2735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 2745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 2765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 2775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 2785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 2795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner addr.sin_family = AF_INET; 2805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner addr.sin_port = 0; 2815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner addr.sin_addr.s_addr = INADDR_ANY; 2825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 || 2845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bind(s, (struct sockaddr *)&addr, addrlen) < 0 || 2855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner listen(s, 1) < 0) { 2865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("Error: inet socket: %s\n", strerror(errno)); 2875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner closesocket(s); 2885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 2905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 2925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 2935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner switch(fork()) { 2945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case -1: 2955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("Error: fork failed: %s\n", strerror(errno)); 2965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(s); 2975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (do_pty == 2) 2985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(master); 2995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 3005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case 0: 3025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Set the DISPLAY */ 3035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (do_pty == 2) { 3045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (void) close(master); 3055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TIOCSCTTY /* XXXXX */ 3065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (void) setsid(); 3075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ioctl(s, TIOCSCTTY, (char *)NULL); 3085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 3095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 3105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner getsockname(s, (struct sockaddr *)&addr, &addrlen); 3115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(s); 3125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* 3135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Connect to the socket 3145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * XXX If any of these fail, we're in trouble! 3155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 3165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s = socket(AF_INET, SOCK_STREAM, 0); 3175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner addr.sin_addr = loopback_addr; 3185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner do { 3195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = connect(s, (struct sockaddr *)&addr, addrlen); 3205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } while (ret < 0 && errno == EINTR); 3215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 3225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0 3245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (x_port >= 0) { 3255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAVE_SETENV 3265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); 3275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner setenv("DISPLAY", buff, 1); 3285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 3295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); 3305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner putenv(buff); 3315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 3325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 3335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 3345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner dup2(s, 0); 3355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner dup2(s, 1); 3365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner dup2(s, 2); 3375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (s = getdtablesize() - 1; s >= 3; s--) 3385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(s); 3395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner i = 0; 3415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bptr = strdup(ex); /* No need to free() this */ 3425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (do_pty == 1) { 3435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Setup "slirp.telnetd -x" */ 3445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner argv[i++] = "slirp.telnetd"; 3455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner argv[i++] = "-x"; 3465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner argv[i++] = bptr; 3475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else 3485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner do { 3495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Change the string into argv[] */ 3505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner curarg = bptr; 3515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (*bptr != ' ' && *bptr != (char)0) 3525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bptr++; 3535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner c = *bptr; 3545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner *bptr++ = (char)0; 3555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner argv[i++] = strdup(curarg); 3565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } while (c); 3575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner argv[i] = NULL; 3595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner execvp(argv[0], (char **)argv); 3605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Ooops, failed, let's tell the user why */ 3625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner { 3635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char buff[256]; 3645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner snprintf(buff, sizeof(buff), 3665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "Error: execvp of %s failed: %s\n", 3675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner argv[0], strerror(errno)); 3685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner write(2, buff, strlen(buff)+1); 3695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 3705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(0); close(1); close(2); /* XXX */ 3715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner exit(1); 3725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner default: 3745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (do_pty == 2) { 3755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(s); 3765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->s = master; 3775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } else { 3785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* 3795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * XXX this could block us... 3805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * XXX Should set a timer here, and if accept() doesn't 3815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * return after X seconds, declare it a failure 3825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * The only reason this will block forever is if socket() 3835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * of connect() fail in the child process 3845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 3855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner do { 3865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->s = accept(s, (struct sockaddr *)&addr, &addrlen); 3875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } while (so->s < 0 && errno == EINTR); 3885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner closesocket(s); 3895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner opt = 1; 3905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); 3915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner opt = 1; 3925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); 3935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 3945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fd_nonblock(so->s); 3955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 3965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Append the telnet options now */ 3975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (so->so_m != NULL && do_pty == 1) { 3985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sbappend(so, so->so_m); 3995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_m = NULL; 4005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 1; 4035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 4055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 4065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef HAVE_STRDUP 4085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar * 4095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstrdup(str) 4105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const char *str; 4115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 4125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *bptr; 4135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bptr = (char *)malloc(strlen(str)+1); 4155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner strcpy(bptr, str); 4165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return bptr; 4185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 4195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 4205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0 4225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid 4235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersnooze_hup(num) 4245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int num; 4255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 4265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int s, ret; 4275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef NO_UNIX_SOCKETS 4285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct sockaddr_un sock_un; 4295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 4305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct sockaddr_in sock_in; 4315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char buff[256]; 4325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ret = -1; 4345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (slirp_socket_passwd) { 4355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s = socket(AF_INET, SOCK_STREAM, 0); 4365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (s < 0) 4375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner slirp_exit(1); 4385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sock_in.sin_family = AF_INET; 4395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sock_in.sin_addr.s_addr = slirp_socket_addr; 4405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sock_in.sin_port = htons(slirp_socket_port); 4415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (connect(s, (struct sockaddr *)&sock_in, sizeof(sock_in)) != 0) 4425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner slirp_exit(1); /* just exit...*/ 4435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sprintf(buff, "kill %s:%d", slirp_socket_passwd, slirp_socket_unit); 4445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner write(s, buff, strlen(buff)+1); 4455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef NO_UNIX_SOCKETS 4475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else { 4485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner s = socket(AF_UNIX, SOCK_STREAM, 0); 4495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (s < 0) 4505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner slirp_exit(1); 4515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sock_un.sun_family = AF_UNIX; 4525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner strcpy(sock_un.sun_path, socket_path); 4535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (connect(s, (struct sockaddr *)&sock_un, 4545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sizeof(sock_un.sun_family) + sizeof(sock_un.sun_path)) != 0) 4555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner slirp_exit(1); 4565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sprintf(buff, "kill none:%d", slirp_socket_unit); 4575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner write(s, buff, strlen(buff)+1); 4585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 4595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 4605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner slirp_exit(0); 4615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 4625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid 4655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersnooze() 4665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 4675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sigset_t s; 4685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int i; 4695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Don't need our data anymore */ 4715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* XXX This makes SunOS barf */ 4725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* brk(0); */ 4735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Close all fd's */ 4755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (i = 255; i >= 0; i--) 4765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(i); 4775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner signal(SIGQUIT, slirp_exit); 4795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner signal(SIGHUP, snooze_hup); 4805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sigemptyset(&s); 4815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Wait for any signal */ 4835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sigsuspend(&s); 4845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Just in case ... */ 4865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner exit(255); 4875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 4885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid 4905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerrelay(s) 4915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int s; 4925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 4935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char buf[8192]; 4945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int n; 4955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fd_set readfds; 4965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct ttys *ttyp; 4975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 4985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Don't need our data anymore */ 4995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* XXX This makes SunOS barf */ 5005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* brk(0); */ 5015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner signal(SIGQUIT, slirp_exit); 5035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner signal(SIGHUP, slirp_exit); 5045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner signal(SIGINT, slirp_exit); 5055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner signal(SIGTERM, slirp_exit); 5065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Fudge to get term_raw and term_restore to work */ 5085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (NULL == (ttyp = tty_attach (0, slirp_tty))) { 5095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint ("Error: tty_attach failed in misc.c:relay()\r\n"); 5105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner slirp_exit (1); 5115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ttyp->fd = 0; 5135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ttyp->flags |= TTY_CTTY; 5145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner term_raw(ttyp); 5155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (1) { 5175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner FD_ZERO(&readfds); 5185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner FD_SET(0, &readfds); 5205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner FD_SET(s, &readfds); 5215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n = select(s+1, &readfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0); 5235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (n <= 0) 5255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner slirp_exit(0); 5265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (FD_ISSET(0, &readfds)) { 5285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n = read(0, buf, 8192); 5295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (n <= 0) 5305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner slirp_exit(0); 5315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n = writen(s, buf, n); 5325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (n <= 0) 5335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner slirp_exit(0); 5345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (FD_ISSET(s, &readfds)) { 5375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n = read(s, buf, 8192); 5385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (n <= 0) 5395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner slirp_exit(0); 5405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner n = writen(0, buf, n); 5415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (n <= 0) 5425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner slirp_exit(0); 5435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 5455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Just in case.... */ 5475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner exit(1); 5485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 5495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 5505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_QEMU 5525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "monitor.h" 5535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid lprint(const char *format, ...) 5555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 5565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner va_list args; 5575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner va_start(args, format); 5595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner monitor_vprintf(cur_mon, format, args); 5605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner va_end(args); 5615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 5625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 5635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint (*lprint_print) _P((void *, const char *, va_list)); 5645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerchar *lprint_ptr, *lprint_ptr2, **lprint_arg; 5655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid 5675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __STDC__ 5685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerlprint(const char *format, ...) 5695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 5705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerlprint(va_alist) va_dcl 5715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 5725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 5735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner va_list args; 5745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __STDC__ 5765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner va_start(args, format); 5775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 5785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *format; 5795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner va_start(args); 5805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner format = va_arg(args, char *); 5815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 5825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0 5835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* If we're printing to an sbuf, make sure there's enough room */ 5845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* XXX +100? */ 5855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (lprint_sb) { 5865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((lprint_ptr - lprint_sb->sb_wptr) >= 5875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (lprint_sb->sb_datalen - (strlen(format) + 100))) { 5885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int deltaw = lprint_sb->sb_wptr - lprint_sb->sb_data; 5895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int deltar = lprint_sb->sb_rptr - lprint_sb->sb_data; 5905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int deltap = lprint_ptr - lprint_sb->sb_data; 5915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint_sb->sb_data = (char *)realloc(lprint_sb->sb_data, 5935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint_sb->sb_datalen + TCP_SNDSPACE); 5945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 5955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Adjust all values */ 5965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint_sb->sb_wptr = lprint_sb->sb_data + deltaw; 5975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint_sb->sb_rptr = lprint_sb->sb_data + deltar; 5985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint_ptr = lprint_sb->sb_data + deltap; 5995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint_sb->sb_datalen += TCP_SNDSPACE; 6015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 6045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (lprint_print) 6055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint_ptr += (*lprint_print)(*lprint_arg, format, args); 6065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Check if they want output to be logged to file as well */ 6085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (lfd) { 6095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* 6105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Remove \r's 6115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * otherwise you'll get ^M all over the file 6125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 6135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int len = strlen(format); 6145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *bptr1, *bptr2; 6155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bptr1 = bptr2 = strdup(format); 6175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner while (len--) { 6195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (*bptr1 == '\r') 6205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner memcpy(bptr1, bptr1+1, len+1); 6215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else 6225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner bptr1++; 6235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner vfprintf(lfd, bptr2, args); 6255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner free(bptr2); 6265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner va_end(args); 6285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 6295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid 6315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneradd_emu(buff) 6325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *buff; 6335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 6345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner u_int lport, fport; 6355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner u_int8_t tos = 0, emu = 0; 6365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char buff1[256], buff2[256], buff4[128]; 6375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *buff3 = buff4; 6385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct emu_t *emup; 6395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct socket *so; 6405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) { 6425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("Error: Bad arguments\r\n"); 6435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return; 6445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) { 6475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lport = 0; 6485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (sscanf(buff1, "%d", &fport) != 1) { 6495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("Error: Bad first argument\r\n"); 6505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return; 6515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) { 6555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner buff3 = 0; 6565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (sscanf(buff2, "%256s", buff1) != 1) { 6575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("Error: Bad second argument\r\n"); 6585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return; 6595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (buff3) { 6635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (strcmp(buff3, "lowdelay") == 0) 6645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tos = IPTOS_LOWDELAY; 6655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else if (strcmp(buff3, "throughput") == 0) 6665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tos = IPTOS_THROUGHPUT; 6675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else { 6685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("Error: Expecting \"lowdelay\"/\"throughput\"\r\n"); 6695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return; 6705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (strcmp(buff1, "ftp") == 0) 6745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner emu = EMU_FTP; 6755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else if (strcmp(buff1, "irc") == 0) 6765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner emu = EMU_IRC; 6775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else if (strcmp(buff1, "none") == 0) 6785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner emu = EMU_NONE; /* ie: no emulation */ 6795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner else { 6805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("Error: Unknown service\r\n"); 6815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return; 6825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* First, check that it isn't already emulated */ 6855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (emup = tcpemu; emup; emup = emup->next) { 6865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (emup->lport == lport && emup->fport == fport) { 6875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("Error: port already emulated\r\n"); 6885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return; 6895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 6915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 6925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* link it */ 6935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner emup = (struct emu_t *)malloc(sizeof (struct emu_t)); 6945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner emup->lport = (u_int16_t)lport; 6955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner emup->fport = (u_int16_t)fport; 6965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner emup->tos = tos; 6975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner emup->emu = emu; 6985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner emup->next = tcpemu; 6995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner tcpemu = emup; 7005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* And finally, mark all current sessions, if any, as being emulated */ 7025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (so = tcb.so_next; so != &tcb; so = so->so_next) { 7035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if ((lport && lport == ntohs(so->so_lport)) || 7045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner (fport && fport == ntohs(so->so_fport))) { 7055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (emu) 7065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_emu = emu; 7075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (tos) 7085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->so_iptos = tos; 7095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 7115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport); 7135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 7145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 7155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef BAD_SPRINTF 7175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef vsprintf 7195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#undef sprintf 7205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 7225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Some BSD-derived systems have a sprintf which returns char * 7235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 7245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint 7265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervsprintf_len(string, format, args) 7275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *string; 7285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner const char *format; 7295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner va_list args; 7305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 7315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner vsprintf(string, format, args); 7325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return strlen(string); 7335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 7345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint 7365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __STDC__ 7375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersprintf_len(char *string, const char *format, ...) 7385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 7395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnersprintf_len(va_alist) va_dcl 7405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 7415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 7425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner va_list args; 7435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __STDC__ 7445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner va_start(args, format); 7455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 7465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *string; 7475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *format; 7485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner va_start(args); 7495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner string = va_arg(args, char *); 7505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner format = va_arg(args, char *); 7515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 7525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner vsprintf(string, format, args); 7535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return strlen(string); 7545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 7555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 7575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid 7595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turneru_sleep(int usec) 7605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 7615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct timeval t; 7625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fd_set fdset; 7635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner FD_ZERO(&fdset); 7655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner t.tv_sec = 0; 7675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner t.tv_usec = usec * 1000; 7685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner select(0, &fdset, &fdset, &fdset, &t); 7705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 7715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 7735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * Set fd blocking and non-blocking 7745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 7755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid 7775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfd_nonblock(int fd) 7785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 7795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef FIONBIO 7805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32 7815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner unsigned long opt = 1; 7825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 7835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int opt = 1; 7845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 7855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ioctlsocket(fd, FIONBIO, &opt); 7875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 7885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int opt; 7895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner opt = fcntl(fd, F_GETFL, 0); 7915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner opt |= O_NONBLOCK; 7925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fcntl(fd, F_SETFL, opt); 7935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 7945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 7955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 7965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid 7975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerfd_block(int fd) 7985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 7995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef FIONBIO 8005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef _WIN32 8015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner unsigned long opt = 0; 8025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 8035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int opt = 0; 8045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 8055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ioctlsocket(fd, FIONBIO, &opt); 8075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 8085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int opt; 8095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner opt = fcntl(fd, F_GETFL, 0); 8115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner opt &= ~O_NONBLOCK; 8125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner fcntl(fd, F_SETFL, opt); 8135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 8145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 8155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 0 8185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* 8195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * invoke RSH 8205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */ 8215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint 8225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerrsh_exec(so,ns, user, host, args) 8235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct socket *so; 8245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner struct socket *ns; 8255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *user; 8265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *host; 8275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char *args; 8285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{ 8295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int fd[2]; 8305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int fd0[2]; 8315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner int s; 8325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner char buff[256]; 8335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner DEBUG_CALL("rsh_exec"); 8355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner DEBUG_ARG("so = %lx", (long)so); 8365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (pipe(fd)<0) { 8385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("Error: pipe failed: %s\n", strerror(errno)); 8395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 8405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* #ifdef HAVE_SOCKETPAIR */ 8425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if 1 8435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (socketpair(PF_UNIX,SOCK_STREAM,0, fd0) == -1) { 8445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(fd[0]); 8455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(fd[1]); 8465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("Error: openpty failed: %s\n", strerror(errno)); 8475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 8485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 8505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (slirp_openpty(&fd0[0], &fd0[1]) == -1) { 8515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(fd[0]); 8525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(fd[1]); 8535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("Error: openpty failed: %s\n", strerror(errno)); 8545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 8555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 8575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner switch(fork()) { 8595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case -1: 8605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner lprint("Error: fork failed: %s\n", strerror(errno)); 8615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(fd[0]); 8625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(fd[1]); 8635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(fd0[0]); 8645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(fd0[1]); 8655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 0; 8665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner case 0: 8685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(fd[0]); 8695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(fd0[0]); 8705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Set the DISPLAY */ 8725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner if (x_port >= 0) { 8735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef HAVE_SETENV 8745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); 8755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner setenv("DISPLAY", buff, 1); 8765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else 8775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen); 8785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner putenv(buff); 8795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 8805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 8815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner dup2(fd0[1], 0); 8835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner dup2(fd0[1], 1); 8845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner dup2(fd[1], 2); 8855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner for (s = 3; s <= 255; s++) 8865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(s); 8875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner execlp("rsh","rsh","-l", user, host, args, NULL); 8895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner /* Ooops, failed, let's tell the user why */ 8915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner sprintf(buff, "Error: execlp of %s failed: %s\n", 8935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner "rsh", strerror(errno)); 8945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner write(2, buff, strlen(buff)+1); 8955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(0); close(1); close(2); /* XXX */ 8965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner exit(1); 8975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 8985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner default: 8995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(fd[1]); 9005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner close(fd0[1]); 9015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner ns->s=fd[0]; 9025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner so->s=fd0[0]; 9035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner 9045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner return 1; 9055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner } 9065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} 9075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif 908