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