Annotation of qemu/slirp/misc.c, revision 1.1.1.4
1.1 root 1: /*
2: * Copyright (c) 1995 Danny Gasparovski.
1.1.1.3 root 3: *
1.1 root 4: * Please read the file COPYRIGHT for the
5: * terms and conditions of the copyright.
6: */
7:
8: #define WANT_SYS_IOCTL_H
9: #include <slirp.h>
10:
1.1.1.3 root 11: u_int curtime, time_fasttimo, last_slowtimo;
1.1 root 12:
13: #if 0
14: int x_port = -1;
15: int x_display = 0;
16: int x_screen = 0;
17:
18: int
19: show_x(buff, inso)
20: char *buff;
21: struct socket *inso;
22: {
23: if (x_port < 0) {
24: lprint("X Redir: X not being redirected.\r\n");
25: } else {
26: lprint("X Redir: In sh/bash/zsh/etc. type: DISPLAY=%s:%d.%d; export DISPLAY\r\n",
27: inet_ntoa(our_addr), x_port, x_screen);
28: lprint("X Redir: In csh/tcsh/etc. type: setenv DISPLAY %s:%d.%d\r\n",
29: inet_ntoa(our_addr), x_port, x_screen);
30: if (x_display)
31: lprint("X Redir: Redirecting to display %d\r\n", x_display);
32: }
1.1.1.3 root 33:
1.1 root 34: return CFG_OK;
35: }
36:
37:
38: /*
39: * XXX Allow more than one X redirection?
40: */
41: void
42: redir_x(inaddr, start_port, display, screen)
43: u_int32_t inaddr;
44: int start_port;
45: int display;
46: int screen;
47: {
48: int i;
1.1.1.3 root 49:
1.1 root 50: if (x_port >= 0) {
51: lprint("X Redir: X already being redirected.\r\n");
52: show_x(0, 0);
53: } else {
54: for (i = 6001 + (start_port-1); i <= 6100; i++) {
55: if (solisten(htons(i), inaddr, htons(6000 + display), 0)) {
56: /* Success */
57: x_port = i - 6000;
58: x_display = display;
59: x_screen = screen;
60: show_x(0, 0);
61: return;
62: }
63: }
64: lprint("X Redir: Error: Couldn't redirect a port for X. Weird.\r\n");
65: }
66: }
67: #endif
68:
69: /*
70: * Get our IP address and put it in our_addr
71: */
72: void
73: getouraddr()
74: {
75: char buff[256];
1.1.1.2 root 76: struct hostent *he = NULL;
1.1.1.3 root 77:
1.1.1.2 root 78: if (gethostname(buff,256) == 0)
79: he = gethostbyname(buff);
80: if (he)
81: our_addr = *(struct in_addr *)he->h_addr;
82: if (our_addr.s_addr == 0)
83: our_addr.s_addr = loopback_addr.s_addr;
1.1 root 84: }
85:
86: struct quehead {
87: struct quehead *qh_link;
88: struct quehead *qh_rlink;
89: };
90:
91: inline void
92: insque(a, b)
93: void *a, *b;
94: {
95: register struct quehead *element = (struct quehead *) a;
96: register struct quehead *head = (struct quehead *) b;
97: element->qh_link = head->qh_link;
98: head->qh_link = (struct quehead *)element;
99: element->qh_rlink = (struct quehead *)head;
100: ((struct quehead *)(element->qh_link))->qh_rlink
101: = (struct quehead *)element;
102: }
103:
104: inline void
105: remque(a)
106: void *a;
107: {
108: register struct quehead *element = (struct quehead *) a;
109: ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
110: ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link;
111: element->qh_rlink = NULL;
112: /* element->qh_link = NULL; TCP FIN1 crashes if you do this. Why ? */
113: }
114:
115: /* #endif */
116:
117:
118: int
119: add_exec(ex_ptr, do_pty, exec, addr, port)
120: struct ex_list **ex_ptr;
121: int do_pty;
122: char *exec;
123: int addr;
124: int port;
125: {
126: struct ex_list *tmp_ptr;
1.1.1.3 root 127:
1.1 root 128: /* First, check if the port is "bound" */
129: for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
130: if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr)
131: return -1;
132: }
1.1.1.3 root 133:
1.1 root 134: tmp_ptr = *ex_ptr;
135: *ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list));
136: (*ex_ptr)->ex_fport = port;
137: (*ex_ptr)->ex_addr = addr;
138: (*ex_ptr)->ex_pty = do_pty;
1.1.1.4 ! root 139: (*ex_ptr)->ex_exec = (do_pty == 3) ? exec : strdup(exec);
1.1 root 140: (*ex_ptr)->ex_next = tmp_ptr;
141: return 0;
142: }
143:
144: #ifndef HAVE_STRERROR
145:
146: /*
147: * For systems with no strerror
148: */
149:
150: extern int sys_nerr;
151: extern char *sys_errlist[];
152:
153: char *
154: strerror(error)
155: int error;
156: {
157: if (error < sys_nerr)
158: return sys_errlist[error];
159: else
160: return "Unknown error.";
161: }
162:
163: #endif
164:
165:
166: #ifdef _WIN32
167:
168: int
1.1.1.3 root 169: fork_exec(struct socket *so, const char *ex, int do_pty)
1.1 root 170: {
171: /* not implemented */
172: return 0;
173: }
174:
175: #else
176:
1.1.1.3 root 177: #ifndef CONFIG_QEMU
1.1 root 178: int
179: slirp_openpty(amaster, aslave)
180: int *amaster, *aslave;
181: {
182: register int master, slave;
183:
184: #ifdef HAVE_GRANTPT
185: char *ptr;
1.1.1.3 root 186:
1.1 root 187: if ((master = open("/dev/ptmx", O_RDWR)) < 0 ||
188: grantpt(master) < 0 ||
189: unlockpt(master) < 0 ||
190: (ptr = ptsname(master)) == NULL) {
191: close(master);
192: return -1;
193: }
1.1.1.3 root 194:
1.1 root 195: if ((slave = open(ptr, O_RDWR)) < 0 ||
196: ioctl(slave, I_PUSH, "ptem") < 0 ||
197: ioctl(slave, I_PUSH, "ldterm") < 0 ||
198: ioctl(slave, I_PUSH, "ttcompat") < 0) {
199: close(master);
200: close(slave);
201: return -1;
202: }
1.1.1.3 root 203:
1.1 root 204: *amaster = master;
205: *aslave = slave;
206: return 0;
1.1.1.3 root 207:
1.1 root 208: #else
1.1.1.3 root 209:
1.1 root 210: static char line[] = "/dev/ptyXX";
211: register const char *cp1, *cp2;
1.1.1.3 root 212:
1.1 root 213: for (cp1 = "pqrsPQRS"; *cp1; cp1++) {
214: line[8] = *cp1;
215: for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) {
216: line[9] = *cp2;
217: if ((master = open(line, O_RDWR, 0)) == -1) {
218: if (errno == ENOENT)
219: return (-1); /* out of ptys */
220: } else {
221: line[5] = 't';
222: /* These will fail */
223: (void) chown(line, getuid(), 0);
224: (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
225: #ifdef HAVE_REVOKE
226: (void) revoke(line);
227: #endif
228: if ((slave = open(line, O_RDWR, 0)) != -1) {
229: *amaster = master;
230: *aslave = slave;
231: return 0;
232: }
233: (void) close(master);
234: line[5] = 'p';
235: }
236: }
237: }
238: errno = ENOENT; /* out of ptys */
239: return (-1);
240: #endif
241: }
1.1.1.3 root 242: #endif
1.1 root 243:
244: /*
245: * XXX This is ugly
246: * We create and bind a socket, then fork off to another
247: * process, which connects to this socket, after which we
248: * exec the wanted program. If something (strange) happens,
249: * the accept() call could block us forever.
1.1.1.3 root 250: *
1.1 root 251: * do_pty = 0 Fork/exec inetd style
252: * do_pty = 1 Fork/exec using slirp.telnetd
253: * do_ptr = 2 Fork/exec using pty
254: */
255: int
1.1.1.3 root 256: fork_exec(struct socket *so, const char *ex, int do_pty)
1.1 root 257: {
258: int s;
259: struct sockaddr_in addr;
1.1.1.4 ! root 260: socklen_t addrlen = sizeof(addr);
1.1 root 261: int opt;
1.1.1.3 root 262: int master = -1;
1.1.1.4 ! root 263: const char *argv[256];
1.1 root 264: #if 0
265: char buff[256];
266: #endif
267: /* don't want to clobber the original */
268: char *bptr;
1.1.1.3 root 269: const char *curarg;
1.1 root 270: int c, i, ret;
1.1.1.3 root 271:
1.1 root 272: DEBUG_CALL("fork_exec");
273: DEBUG_ARG("so = %lx", (long)so);
274: DEBUG_ARG("ex = %lx", (long)ex);
275: DEBUG_ARG("do_pty = %lx", (long)do_pty);
1.1.1.3 root 276:
1.1 root 277: if (do_pty == 2) {
1.1.1.3 root 278: #if 0
1.1 root 279: if (slirp_openpty(&master, &s) == -1) {
280: lprint("Error: openpty failed: %s\n", strerror(errno));
281: return 0;
282: }
1.1.1.3 root 283: #else
284: return 0;
285: #endif
1.1 root 286: } else {
287: addr.sin_family = AF_INET;
288: addr.sin_port = 0;
289: addr.sin_addr.s_addr = INADDR_ANY;
1.1.1.3 root 290:
1.1 root 291: if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
292: bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
293: listen(s, 1) < 0) {
294: lprint("Error: inet socket: %s\n", strerror(errno));
295: closesocket(s);
1.1.1.3 root 296:
1.1 root 297: return 0;
298: }
299: }
1.1.1.3 root 300:
1.1 root 301: switch(fork()) {
302: case -1:
303: lprint("Error: fork failed: %s\n", strerror(errno));
304: close(s);
305: if (do_pty == 2)
306: close(master);
307: return 0;
1.1.1.3 root 308:
1.1 root 309: case 0:
310: /* Set the DISPLAY */
311: if (do_pty == 2) {
312: (void) close(master);
313: #ifdef TIOCSCTTY /* XXXXX */
314: (void) setsid();
315: ioctl(s, TIOCSCTTY, (char *)NULL);
316: #endif
317: } else {
318: getsockname(s, (struct sockaddr *)&addr, &addrlen);
319: close(s);
320: /*
321: * Connect to the socket
322: * XXX If any of these fail, we're in trouble!
323: */
324: s = socket(AF_INET, SOCK_STREAM, 0);
325: addr.sin_addr = loopback_addr;
326: do {
327: ret = connect(s, (struct sockaddr *)&addr, addrlen);
328: } while (ret < 0 && errno == EINTR);
329: }
1.1.1.3 root 330:
1.1 root 331: #if 0
332: if (x_port >= 0) {
333: #ifdef HAVE_SETENV
334: sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
335: setenv("DISPLAY", buff, 1);
336: #else
337: sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
338: putenv(buff);
339: #endif
340: }
1.1.1.3 root 341: #endif
1.1 root 342: dup2(s, 0);
343: dup2(s, 1);
344: dup2(s, 2);
1.1.1.3 root 345: for (s = getdtablesize() - 1; s >= 3; s--)
1.1 root 346: close(s);
1.1.1.3 root 347:
1.1 root 348: i = 0;
349: bptr = strdup(ex); /* No need to free() this */
350: if (do_pty == 1) {
351: /* Setup "slirp.telnetd -x" */
352: argv[i++] = "slirp.telnetd";
353: argv[i++] = "-x";
354: argv[i++] = bptr;
355: } else
356: do {
357: /* Change the string into argv[] */
358: curarg = bptr;
359: while (*bptr != ' ' && *bptr != (char)0)
360: bptr++;
361: c = *bptr;
362: *bptr++ = (char)0;
363: argv[i++] = strdup(curarg);
364: } while (c);
1.1.1.3 root 365:
1.1 root 366: argv[i] = 0;
1.1.1.4 ! root 367: execvp(argv[0], (char **)argv);
1.1.1.3 root 368:
1.1 root 369: /* Ooops, failed, let's tell the user why */
370: {
371: char buff[256];
1.1.1.3 root 372:
1.1.1.4 ! root 373: snprintf(buff, sizeof(buff),
! 374: "Error: execvp of %s failed: %s\n",
! 375: argv[0], strerror(errno));
1.1 root 376: write(2, buff, strlen(buff)+1);
377: }
378: close(0); close(1); close(2); /* XXX */
379: exit(1);
1.1.1.3 root 380:
1.1 root 381: default:
382: if (do_pty == 2) {
383: close(s);
384: so->s = master;
385: } else {
386: /*
387: * XXX this could block us...
388: * XXX Should set a timer here, and if accept() doesn't
389: * return after X seconds, declare it a failure
390: * The only reason this will block forever is if socket()
391: * of connect() fail in the child process
392: */
393: do {
394: so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
395: } while (so->s < 0 && errno == EINTR);
396: closesocket(s);
397: opt = 1;
398: setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));
399: opt = 1;
400: setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
401: }
402: fd_nonblock(so->s);
1.1.1.3 root 403:
1.1 root 404: /* Append the telnet options now */
405: if (so->so_m != 0 && do_pty == 1) {
406: sbappend(so, so->so_m);
407: so->so_m = 0;
408: }
1.1.1.3 root 409:
1.1 root 410: return 1;
411: }
412: }
413: #endif
414:
415: #ifndef HAVE_STRDUP
416: char *
417: strdup(str)
418: const char *str;
419: {
420: char *bptr;
1.1.1.3 root 421:
1.1 root 422: bptr = (char *)malloc(strlen(str)+1);
423: strcpy(bptr, str);
1.1.1.3 root 424:
1.1 root 425: return bptr;
426: }
427: #endif
428:
429: #if 0
430: void
431: snooze_hup(num)
432: int num;
433: {
434: int s, ret;
435: #ifndef NO_UNIX_SOCKETS
436: struct sockaddr_un sock_un;
437: #endif
438: struct sockaddr_in sock_in;
439: char buff[256];
1.1.1.3 root 440:
1.1 root 441: ret = -1;
442: if (slirp_socket_passwd) {
443: s = socket(AF_INET, SOCK_STREAM, 0);
444: if (s < 0)
445: slirp_exit(1);
446: sock_in.sin_family = AF_INET;
447: sock_in.sin_addr.s_addr = slirp_socket_addr;
448: sock_in.sin_port = htons(slirp_socket_port);
449: if (connect(s, (struct sockaddr *)&sock_in, sizeof(sock_in)) != 0)
450: slirp_exit(1); /* just exit...*/
451: sprintf(buff, "kill %s:%d", slirp_socket_passwd, slirp_socket_unit);
452: write(s, buff, strlen(buff)+1);
453: }
454: #ifndef NO_UNIX_SOCKETS
455: else {
456: s = socket(AF_UNIX, SOCK_STREAM, 0);
457: if (s < 0)
458: slirp_exit(1);
459: sock_un.sun_family = AF_UNIX;
460: strcpy(sock_un.sun_path, socket_path);
461: if (connect(s, (struct sockaddr *)&sock_un,
462: sizeof(sock_un.sun_family) + sizeof(sock_un.sun_path)) != 0)
463: slirp_exit(1);
464: sprintf(buff, "kill none:%d", slirp_socket_unit);
465: write(s, buff, strlen(buff)+1);
466: }
467: #endif
468: slirp_exit(0);
469: }
1.1.1.3 root 470:
471:
1.1 root 472: void
473: snooze()
474: {
475: sigset_t s;
476: int i;
1.1.1.3 root 477:
1.1 root 478: /* Don't need our data anymore */
479: /* XXX This makes SunOS barf */
480: /* brk(0); */
1.1.1.3 root 481:
1.1 root 482: /* Close all fd's */
483: for (i = 255; i >= 0; i--)
484: close(i);
1.1.1.3 root 485:
1.1 root 486: signal(SIGQUIT, slirp_exit);
487: signal(SIGHUP, snooze_hup);
488: sigemptyset(&s);
1.1.1.3 root 489:
1.1 root 490: /* Wait for any signal */
491: sigsuspend(&s);
1.1.1.3 root 492:
1.1 root 493: /* Just in case ... */
494: exit(255);
495: }
496:
497: void
498: relay(s)
499: int s;
500: {
501: char buf[8192];
502: int n;
503: fd_set readfds;
504: struct ttys *ttyp;
1.1.1.3 root 505:
1.1 root 506: /* Don't need our data anymore */
507: /* XXX This makes SunOS barf */
508: /* brk(0); */
1.1.1.3 root 509:
1.1 root 510: signal(SIGQUIT, slirp_exit);
511: signal(SIGHUP, slirp_exit);
512: signal(SIGINT, slirp_exit);
513: signal(SIGTERM, slirp_exit);
1.1.1.3 root 514:
1.1 root 515: /* Fudge to get term_raw and term_restore to work */
516: if (NULL == (ttyp = tty_attach (0, slirp_tty))) {
517: lprint ("Error: tty_attach failed in misc.c:relay()\r\n");
518: slirp_exit (1);
519: }
520: ttyp->fd = 0;
521: ttyp->flags |= TTY_CTTY;
522: term_raw(ttyp);
1.1.1.3 root 523:
1.1 root 524: while (1) {
525: FD_ZERO(&readfds);
1.1.1.3 root 526:
1.1 root 527: FD_SET(0, &readfds);
528: FD_SET(s, &readfds);
1.1.1.3 root 529:
1.1 root 530: n = select(s+1, &readfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0);
1.1.1.3 root 531:
1.1 root 532: if (n <= 0)
533: slirp_exit(0);
1.1.1.3 root 534:
1.1 root 535: if (FD_ISSET(0, &readfds)) {
536: n = read(0, buf, 8192);
537: if (n <= 0)
538: slirp_exit(0);
539: n = writen(s, buf, n);
540: if (n <= 0)
541: slirp_exit(0);
542: }
1.1.1.3 root 543:
1.1 root 544: if (FD_ISSET(s, &readfds)) {
545: n = read(s, buf, 8192);
546: if (n <= 0)
547: slirp_exit(0);
548: n = writen(0, buf, n);
549: if (n <= 0)
550: slirp_exit(0);
551: }
552: }
1.1.1.3 root 553:
1.1 root 554: /* Just in case.... */
555: exit(1);
556: }
557: #endif
558:
1.1.1.3 root 559: #ifdef CONFIG_QEMU
560: extern void term_vprintf(const char *fmt, va_list ap);
561:
562: void lprint(const char *format, ...)
563: {
564: va_list args;
565:
566: va_start(args, format);
567: term_vprintf(format, args);
568: va_end(args);
569: }
570: #else
1.1 root 571: int (*lprint_print) _P((void *, const char *, va_list));
572: char *lprint_ptr, *lprint_ptr2, **lprint_arg;
573:
574: void
575: #ifdef __STDC__
576: lprint(const char *format, ...)
577: #else
578: lprint(va_alist) va_dcl
579: #endif
580: {
581: va_list args;
1.1.1.3 root 582:
1.1 root 583: #ifdef __STDC__
584: va_start(args, format);
585: #else
586: char *format;
587: va_start(args);
588: format = va_arg(args, char *);
589: #endif
590: #if 0
591: /* If we're printing to an sbuf, make sure there's enough room */
592: /* XXX +100? */
593: if (lprint_sb) {
594: if ((lprint_ptr - lprint_sb->sb_wptr) >=
595: (lprint_sb->sb_datalen - (strlen(format) + 100))) {
596: int deltaw = lprint_sb->sb_wptr - lprint_sb->sb_data;
597: int deltar = lprint_sb->sb_rptr - lprint_sb->sb_data;
598: int deltap = lprint_ptr - lprint_sb->sb_data;
1.1.1.3 root 599:
1.1 root 600: lprint_sb->sb_data = (char *)realloc(lprint_sb->sb_data,
601: lprint_sb->sb_datalen + TCP_SNDSPACE);
1.1.1.3 root 602:
1.1 root 603: /* Adjust all values */
604: lprint_sb->sb_wptr = lprint_sb->sb_data + deltaw;
605: lprint_sb->sb_rptr = lprint_sb->sb_data + deltar;
606: lprint_ptr = lprint_sb->sb_data + deltap;
1.1.1.3 root 607:
1.1 root 608: lprint_sb->sb_datalen += TCP_SNDSPACE;
609: }
610: }
1.1.1.3 root 611: #endif
1.1 root 612: if (lprint_print)
613: lprint_ptr += (*lprint_print)(*lprint_arg, format, args);
1.1.1.3 root 614:
1.1 root 615: /* Check if they want output to be logged to file as well */
616: if (lfd) {
1.1.1.3 root 617: /*
1.1 root 618: * Remove \r's
619: * otherwise you'll get ^M all over the file
620: */
621: int len = strlen(format);
622: char *bptr1, *bptr2;
1.1.1.3 root 623:
1.1 root 624: bptr1 = bptr2 = strdup(format);
1.1.1.3 root 625:
1.1 root 626: while (len--) {
627: if (*bptr1 == '\r')
628: memcpy(bptr1, bptr1+1, len+1);
629: else
630: bptr1++;
631: }
632: vfprintf(lfd, bptr2, args);
633: free(bptr2);
634: }
635: va_end(args);
636: }
637:
638: void
639: add_emu(buff)
640: char *buff;
641: {
642: u_int lport, fport;
643: u_int8_t tos = 0, emu = 0;
644: char buff1[256], buff2[256], buff4[128];
645: char *buff3 = buff4;
646: struct emu_t *emup;
647: struct socket *so;
1.1.1.3 root 648:
1.1 root 649: if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) {
650: lprint("Error: Bad arguments\r\n");
651: return;
652: }
1.1.1.3 root 653:
1.1 root 654: if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) {
655: lport = 0;
656: if (sscanf(buff1, "%d", &fport) != 1) {
657: lprint("Error: Bad first argument\r\n");
658: return;
659: }
660: }
1.1.1.3 root 661:
1.1 root 662: if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) {
663: buff3 = 0;
664: if (sscanf(buff2, "%256s", buff1) != 1) {
665: lprint("Error: Bad second argument\r\n");
666: return;
667: }
668: }
1.1.1.3 root 669:
1.1 root 670: if (buff3) {
671: if (strcmp(buff3, "lowdelay") == 0)
672: tos = IPTOS_LOWDELAY;
673: else if (strcmp(buff3, "throughput") == 0)
674: tos = IPTOS_THROUGHPUT;
675: else {
676: lprint("Error: Expecting \"lowdelay\"/\"throughput\"\r\n");
677: return;
678: }
679: }
1.1.1.3 root 680:
1.1 root 681: if (strcmp(buff1, "ftp") == 0)
682: emu = EMU_FTP;
683: else if (strcmp(buff1, "irc") == 0)
684: emu = EMU_IRC;
685: else if (strcmp(buff1, "none") == 0)
686: emu = EMU_NONE; /* ie: no emulation */
687: else {
688: lprint("Error: Unknown service\r\n");
689: return;
690: }
1.1.1.3 root 691:
1.1 root 692: /* First, check that it isn't already emulated */
693: for (emup = tcpemu; emup; emup = emup->next) {
694: if (emup->lport == lport && emup->fport == fport) {
695: lprint("Error: port already emulated\r\n");
696: return;
697: }
698: }
1.1.1.3 root 699:
1.1 root 700: /* link it */
701: emup = (struct emu_t *)malloc(sizeof (struct emu_t));
702: emup->lport = (u_int16_t)lport;
703: emup->fport = (u_int16_t)fport;
704: emup->tos = tos;
705: emup->emu = emu;
706: emup->next = tcpemu;
707: tcpemu = emup;
1.1.1.3 root 708:
1.1 root 709: /* And finally, mark all current sessions, if any, as being emulated */
710: for (so = tcb.so_next; so != &tcb; so = so->so_next) {
711: if ((lport && lport == ntohs(so->so_lport)) ||
712: (fport && fport == ntohs(so->so_fport))) {
713: if (emu)
714: so->so_emu = emu;
715: if (tos)
716: so->so_iptos = tos;
717: }
718: }
1.1.1.3 root 719:
1.1 root 720: lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport);
721: }
1.1.1.3 root 722: #endif
1.1 root 723:
724: #ifdef BAD_SPRINTF
725:
726: #undef vsprintf
727: #undef sprintf
728:
729: /*
730: * Some BSD-derived systems have a sprintf which returns char *
731: */
732:
733: int
734: vsprintf_len(string, format, args)
735: char *string;
736: const char *format;
737: va_list args;
738: {
739: vsprintf(string, format, args);
740: return strlen(string);
741: }
742:
743: int
744: #ifdef __STDC__
745: sprintf_len(char *string, const char *format, ...)
746: #else
747: sprintf_len(va_alist) va_dcl
748: #endif
749: {
750: va_list args;
751: #ifdef __STDC__
752: va_start(args, format);
753: #else
754: char *string;
755: char *format;
756: va_start(args);
757: string = va_arg(args, char *);
758: format = va_arg(args, char *);
759: #endif
760: vsprintf(string, format, args);
761: return strlen(string);
762: }
763:
764: #endif
765:
766: void
767: u_sleep(usec)
768: int usec;
769: {
770: struct timeval t;
771: fd_set fdset;
1.1.1.3 root 772:
1.1 root 773: FD_ZERO(&fdset);
1.1.1.3 root 774:
1.1 root 775: t.tv_sec = 0;
776: t.tv_usec = usec * 1000;
1.1.1.3 root 777:
1.1 root 778: select(0, &fdset, &fdset, &fdset, &t);
779: }
780:
781: /*
782: * Set fd blocking and non-blocking
783: */
784:
785: void
786: fd_nonblock(fd)
787: int fd;
788: {
789: #ifdef FIONBIO
790: int opt = 1;
1.1.1.3 root 791:
1.1 root 792: ioctlsocket(fd, FIONBIO, &opt);
793: #else
794: int opt;
1.1.1.3 root 795:
1.1 root 796: opt = fcntl(fd, F_GETFL, 0);
797: opt |= O_NONBLOCK;
798: fcntl(fd, F_SETFL, opt);
799: #endif
800: }
801:
802: void
803: fd_block(fd)
804: int fd;
805: {
806: #ifdef FIONBIO
807: int opt = 0;
1.1.1.3 root 808:
1.1 root 809: ioctlsocket(fd, FIONBIO, &opt);
810: #else
811: int opt;
1.1.1.3 root 812:
1.1 root 813: opt = fcntl(fd, F_GETFL, 0);
814: opt &= ~O_NONBLOCK;
815: fcntl(fd, F_SETFL, opt);
816: #endif
817: }
818:
819:
820: #if 0
821: /*
822: * invoke RSH
823: */
824: int
825: rsh_exec(so,ns, user, host, args)
826: struct socket *so;
827: struct socket *ns;
828: char *user;
829: char *host;
830: char *args;
831: {
832: int fd[2];
833: int fd0[2];
834: int s;
835: char buff[256];
1.1.1.3 root 836:
1.1 root 837: DEBUG_CALL("rsh_exec");
838: DEBUG_ARG("so = %lx", (long)so);
1.1.1.3 root 839:
1.1 root 840: if (pipe(fd)<0) {
841: lprint("Error: pipe failed: %s\n", strerror(errno));
842: return 0;
843: }
844: /* #ifdef HAVE_SOCKETPAIR */
845: #if 1
846: if (socketpair(PF_UNIX,SOCK_STREAM,0, fd0) == -1) {
847: close(fd[0]);
848: close(fd[1]);
849: lprint("Error: openpty failed: %s\n", strerror(errno));
850: return 0;
851: }
852: #else
853: if (slirp_openpty(&fd0[0], &fd0[1]) == -1) {
854: close(fd[0]);
855: close(fd[1]);
856: lprint("Error: openpty failed: %s\n", strerror(errno));
857: return 0;
858: }
859: #endif
1.1.1.3 root 860:
1.1 root 861: switch(fork()) {
862: case -1:
863: lprint("Error: fork failed: %s\n", strerror(errno));
864: close(fd[0]);
865: close(fd[1]);
866: close(fd0[0]);
867: close(fd0[1]);
868: return 0;
1.1.1.3 root 869:
1.1 root 870: case 0:
871: close(fd[0]);
872: close(fd0[0]);
1.1.1.3 root 873:
1.1 root 874: /* Set the DISPLAY */
875: if (x_port >= 0) {
876: #ifdef HAVE_SETENV
877: sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
878: setenv("DISPLAY", buff, 1);
879: #else
880: sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
881: putenv(buff);
882: #endif
883: }
1.1.1.3 root 884:
1.1 root 885: dup2(fd0[1], 0);
886: dup2(fd0[1], 1);
887: dup2(fd[1], 2);
888: for (s = 3; s <= 255; s++)
889: close(s);
1.1.1.3 root 890:
1.1 root 891: execlp("rsh","rsh","-l", user, host, args, NULL);
1.1.1.3 root 892:
1.1 root 893: /* Ooops, failed, let's tell the user why */
1.1.1.3 root 894:
895: sprintf(buff, "Error: execlp of %s failed: %s\n",
1.1 root 896: "rsh", strerror(errno));
897: write(2, buff, strlen(buff)+1);
898: close(0); close(1); close(2); /* XXX */
899: exit(1);
1.1.1.3 root 900:
1.1 root 901: default:
902: close(fd[1]);
903: close(fd0[1]);
904: ns->s=fd[0];
905: so->s=fd0[0];
1.1.1.3 root 906:
1.1 root 907: return 1;
908: }
909: }
910: #endif
unix.superglobalmegacorp.com