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