Statistics
| Branch: | Revision:

root / slirp / misc.c @ 31a60e22

History | View | Annotate | Download (19.1 kB)

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 <slirp.h>
10

    
11
u_int curtime, time_fasttimo, last_slowtimo, detach_time;
12
u_int detach_wait = 600000;        /* 10 minutes */
13

    
14
#if 0
15
int x_port = -1;
16
int x_display = 0;
17
int x_screen = 0;
18

19
int
20
show_x(buff, inso)
21
        char *buff;
22
        struct socket *inso;
23
{
24
        if (x_port < 0) {
25
                lprint("X Redir: X not being redirected.\r\n");
26
        } else {
27
                lprint("X Redir: In sh/bash/zsh/etc. type: DISPLAY=%s:%d.%d; export DISPLAY\r\n",
28
                      inet_ntoa(our_addr), x_port, x_screen);
29
                lprint("X Redir: In csh/tcsh/etc. type:    setenv DISPLAY %s:%d.%d\r\n",
30
                      inet_ntoa(our_addr), x_port, x_screen);
31
                if (x_display)
32
                   lprint("X Redir: Redirecting to display %d\r\n", x_display);
33
        }
34

35
        return CFG_OK;
36
}
37

38

39
/*
40
 * XXX Allow more than one X redirection?
41
 */
42
void
43
redir_x(inaddr, start_port, display, screen)
44
        u_int32_t inaddr;
45
        int start_port;
46
        int display;
47
        int screen;
48
{
49
        int i;
50

51
        if (x_port >= 0) {
52
                lprint("X Redir: X already being redirected.\r\n");
53
                show_x(0, 0);
54
        } else {
55
                for (i = 6001 + (start_port-1); i <= 6100; i++) {
56
                        if (solisten(htons(i), inaddr, htons(6000 + display), 0)) {
57
                                /* Success */
58
                                x_port = i - 6000;
59
                                x_display = display;
60
                                x_screen = screen;
61
                                show_x(0, 0);
62
                                return;
63
                        }
64
                }
65
                lprint("X Redir: Error: Couldn't redirect a port for X. Weird.\r\n");
66
        }
67
}
68
#endif
69

    
70
#ifndef HAVE_INET_ATON
71
int
72
inet_aton(cp, ia)
73
        const char *cp;
74
        struct in_addr *ia;
75
{
76
        u_int32_t addr = inet_addr(cp);
77
        if (addr == 0xffffffff)
78
                return 0;
79
        ia->s_addr = addr;
80
        return 1;
81
}
82
#endif
83

    
84
/*
85
 * Get our IP address and put it in our_addr
86
 */
87
void
88
getouraddr()
89
{
90
        char buff[256];
91
        struct hostent *he = NULL;
92

    
93
        if (gethostname(buff,256) == 0)
94
            he = gethostbyname(buff);
95
        if (he)
96
            our_addr = *(struct in_addr *)he->h_addr;
97
        if (our_addr.s_addr == 0)
98
            our_addr.s_addr = loopback_addr.s_addr;
99
}
100

    
101
#if SIZEOF_CHAR_P == 8
102

    
103
struct quehead_32 {
104
        u_int32_t qh_link;
105
        u_int32_t qh_rlink;
106
};
107

    
108
inline void
109
insque_32(a, b)
110
        void *a;
111
        void *b;
112
{
113
        register struct quehead_32 *element = (struct quehead_32 *) a;
114
        register struct quehead_32 *head = (struct quehead_32 *) b;
115
        element->qh_link = head->qh_link;
116
        head->qh_link = (u_int32_t)element;
117
        element->qh_rlink = (u_int32_t)head;
118
        ((struct quehead_32 *)(element->qh_link))->qh_rlink
119
        = (u_int32_t)element;
120
}
121

    
122
inline void
123
remque_32(a)
124
        void *a;
125
{
126
        register struct quehead_32 *element = (struct quehead_32 *) a;
127
        ((struct quehead_32 *)(element->qh_link))->qh_rlink = element->qh_rlink;
128
        ((struct quehead_32 *)(element->qh_rlink))->qh_link = element->qh_link;
129
        element->qh_rlink = 0;
130
}
131

    
132
#endif /* SIZEOF_CHAR_P == 8 */
133

    
134
struct quehead {
135
        struct quehead *qh_link;
136
        struct quehead *qh_rlink;
137
};
138

    
139
inline void
140
insque(a, b)
141
        void *a, *b;
142
{
143
        register struct quehead *element = (struct quehead *) a;
144
        register struct quehead *head = (struct quehead *) b;
145
        element->qh_link = head->qh_link;
146
        head->qh_link = (struct quehead *)element;
147
        element->qh_rlink = (struct quehead *)head;
148
        ((struct quehead *)(element->qh_link))->qh_rlink
149
        = (struct quehead *)element;
150
}
151

    
152
inline void
153
remque(a)
154
     void *a;
155
{
156
  register struct quehead *element = (struct quehead *) a;
157
  ((struct quehead *)(element->qh_link))->qh_rlink = element->qh_rlink;
158
  ((struct quehead *)(element->qh_rlink))->qh_link = element->qh_link;
159
  element->qh_rlink = NULL;
160
  /*  element->qh_link = NULL;  TCP FIN1 crashes if you do this.  Why ? */
161
}
162

    
163
/* #endif */
164

    
165

    
166
int
167
add_exec(ex_ptr, do_pty, exec, addr, port)
168
        struct ex_list **ex_ptr;
169
        int do_pty;
170
        char *exec;
171
        int addr;
172
        int port;
173
{
174
        struct ex_list *tmp_ptr;
175

    
176
        /* First, check if the port is "bound" */
177
        for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
178
                if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr)
179
                   return -1;
180
        }
181

    
182
        tmp_ptr = *ex_ptr;
183
        *ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list));
184
        (*ex_ptr)->ex_fport = port;
185
        (*ex_ptr)->ex_addr = addr;
186
        (*ex_ptr)->ex_pty = do_pty;
187
        (*ex_ptr)->ex_exec = strdup(exec);
188
        (*ex_ptr)->ex_next = tmp_ptr;
189
        return 0;
190
}
191

    
192
#ifndef HAVE_STRERROR
193

    
194
/*
195
 * For systems with no strerror
196
 */
197

    
198
extern int sys_nerr;
199
extern char *sys_errlist[];
200

    
201
char *
202
strerror(error)
203
        int error;
204
{
205
        if (error < sys_nerr)
206
           return sys_errlist[error];
207
        else
208
           return "Unknown error.";
209
}
210

    
211
#endif
212

    
213

    
214
#ifdef _WIN32
215

    
216
int
217
fork_exec(so, ex, do_pty)
218
        struct socket *so;
219
        char *ex;
220
        int do_pty;
221
{
222
    /* not implemented */
223
    return 0;
224
}
225

    
226
#else
227

    
228
int
229
slirp_openpty(amaster, aslave)
230
     int *amaster, *aslave;
231
{
232
        register int master, slave;
233

    
234
#ifdef HAVE_GRANTPT
235
        char *ptr;
236

    
237
        if ((master = open("/dev/ptmx", O_RDWR)) < 0 ||
238
            grantpt(master) < 0 ||
239
            unlockpt(master) < 0 ||
240
            (ptr = ptsname(master)) == NULL)  {
241
                close(master);
242
                return -1;
243
        }
244

    
245
        if ((slave = open(ptr, O_RDWR)) < 0 ||
246
            ioctl(slave, I_PUSH, "ptem") < 0 ||
247
            ioctl(slave, I_PUSH, "ldterm") < 0 ||
248
            ioctl(slave, I_PUSH, "ttcompat") < 0) {
249
                close(master);
250
                close(slave);
251
                return -1;
252
        }
253

    
254
        *amaster = master;
255
        *aslave = slave;
256
        return 0;
257

    
258
#else
259

    
260
        static char line[] = "/dev/ptyXX";
261
        register const char *cp1, *cp2;
262

    
263
        for (cp1 = "pqrsPQRS"; *cp1; cp1++) {
264
                line[8] = *cp1;
265
                for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) {
266
                        line[9] = *cp2;
267
                        if ((master = open(line, O_RDWR, 0)) == -1) {
268
                                if (errno == ENOENT)
269
                                   return (-1);    /* out of ptys */
270
                        } else {
271
                                line[5] = 't';
272
                                /* These will fail */
273
                                (void) chown(line, getuid(), 0);
274
                                (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
275
#ifdef HAVE_REVOKE
276
                                (void) revoke(line);
277
#endif
278
                                if ((slave = open(line, O_RDWR, 0)) != -1) {
279
                                        *amaster = master;
280
                                        *aslave = slave;
281
                                        return 0;
282
                                }
283
                                (void) close(master);
284
                                line[5] = 'p';
285
                        }
286
                }
287
        }
288
        errno = ENOENT; /* out of ptys */
289
        return (-1);
290
#endif
291
}
292

    
293
/*
294
 * XXX This is ugly
295
 * We create and bind a socket, then fork off to another
296
 * process, which connects to this socket, after which we
297
 * exec the wanted program.  If something (strange) happens,
298
 * the accept() call could block us forever.
299
 *
300
 * do_pty = 0   Fork/exec inetd style
301
 * do_pty = 1   Fork/exec using slirp.telnetd
302
 * do_ptr = 2   Fork/exec using pty
303
 */
304
int
305
fork_exec(so, ex, do_pty)
306
        struct socket *so;
307
        char *ex;
308
        int do_pty;
309
{
310
        int s;
311
        struct sockaddr_in addr;
312
        int addrlen = sizeof(addr);
313
        int opt;
314
        int master;
315
        char *argv[256];
316
#if 0
317
        char buff[256];
318
#endif
319
        /* don't want to clobber the original */
320
        char *bptr;
321
        char *curarg;
322
        int c, i, ret;
323

    
324
        DEBUG_CALL("fork_exec");
325
        DEBUG_ARG("so = %lx", (long)so);
326
        DEBUG_ARG("ex = %lx", (long)ex);
327
        DEBUG_ARG("do_pty = %lx", (long)do_pty);
328

    
329
        if (do_pty == 2) {
330
                if (slirp_openpty(&master, &s) == -1) {
331
                        lprint("Error: openpty failed: %s\n", strerror(errno));
332
                        return 0;
333
                }
334
        } else {
335
                addr.sin_family = AF_INET;
336
                addr.sin_port = 0;
337
                addr.sin_addr.s_addr = INADDR_ANY;
338

    
339
                if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
340
                    bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
341
                    listen(s, 1) < 0) {
342
                        lprint("Error: inet socket: %s\n", strerror(errno));
343
                        closesocket(s);
344

    
345
                        return 0;
346
                }
347
        }
348

    
349
        switch(fork()) {
350
         case -1:
351
                lprint("Error: fork failed: %s\n", strerror(errno));
352
                close(s);
353
                if (do_pty == 2)
354
                   close(master);
355
                return 0;
356

    
357
         case 0:
358
                /* Set the DISPLAY */
359
                if (do_pty == 2) {
360
                        (void) close(master);
361
#ifdef TIOCSCTTY /* XXXXX */
362
                        (void) setsid();
363
                        ioctl(s, TIOCSCTTY, (char *)NULL);
364
#endif
365
                } else {
366
                        getsockname(s, (struct sockaddr *)&addr, &addrlen);
367
                        close(s);
368
                        /*
369
                         * Connect to the socket
370
                         * XXX If any of these fail, we're in trouble!
371
                          */
372
                        s = socket(AF_INET, SOCK_STREAM, 0);
373
                        addr.sin_addr = loopback_addr;
374
                        do {
375
                            ret = connect(s, (struct sockaddr *)&addr, addrlen);
376
                        } while (ret < 0 && errno == EINTR);
377
                }
378

    
379
#if 0
380
                if (x_port >= 0) {
381
#ifdef HAVE_SETENV
382
                        sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
383
                        setenv("DISPLAY", buff, 1);
384
#else
385
                        sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
386
                        putenv(buff);
387
#endif
388
                }
389
#endif
390
                dup2(s, 0);
391
                dup2(s, 1);
392
                dup2(s, 2);
393
                for (s = 3; s <= 255; s++)
394
                   close(s);
395

    
396
                i = 0;
397
                bptr = strdup(ex); /* No need to free() this */
398
                if (do_pty == 1) {
399
                        /* Setup "slirp.telnetd -x" */
400
                        argv[i++] = "slirp.telnetd";
401
                        argv[i++] = "-x";
402
                        argv[i++] = bptr;
403
                } else
404
                   do {
405
                        /* Change the string into argv[] */
406
                        curarg = bptr;
407
                        while (*bptr != ' ' && *bptr != (char)0)
408
                           bptr++;
409
                        c = *bptr;
410
                        *bptr++ = (char)0;
411
                        argv[i++] = strdup(curarg);
412
                   } while (c);
413

    
414
                argv[i] = 0;
415
                execvp(argv[0], argv);
416

    
417
                /* Ooops, failed, let's tell the user why */
418
                  {
419
                          char buff[256];
420

    
421
                          sprintf(buff, "Error: execvp of %s failed: %s\n",
422
                                  argv[0], strerror(errno));
423
                          write(2, buff, strlen(buff)+1);
424
                  }
425
                close(0); close(1); close(2); /* XXX */
426
                exit(1);
427

    
428
         default:
429
                if (do_pty == 2) {
430
                        close(s);
431
                        so->s = master;
432
                } else {
433
                        /*
434
                         * XXX this could block us...
435
                         * XXX Should set a timer here, and if accept() doesn't
436
                          * return after X seconds, declare it a failure
437
                          * The only reason this will block forever is if socket()
438
                          * of connect() fail in the child process
439
                          */
440
                        do {
441
                            so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
442
                        } while (so->s < 0 && errno == EINTR);
443
                        closesocket(s);
444
                        opt = 1;
445
                        setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));
446
                        opt = 1;
447
                        setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
448
                }
449
                fd_nonblock(so->s);
450

    
451
                /* Append the telnet options now */
452
                if (so->so_m != 0 && do_pty == 1)  {
453
                        sbappend(so, so->so_m);
454
                        so->so_m = 0;
455
                }
456

    
457
                return 1;
458
        }
459
}
460
#endif
461

    
462
#ifndef HAVE_STRDUP
463
char *
464
strdup(str)
465
        const char *str;
466
{
467
        char *bptr;
468

    
469
        bptr = (char *)malloc(strlen(str)+1);
470
        strcpy(bptr, str);
471

    
472
        return bptr;
473
}
474
#endif
475

    
476
#if 0
477
void
478
snooze_hup(num)
479
        int num;
480
{
481
        int s, ret;
482
#ifndef NO_UNIX_SOCKETS
483
        struct sockaddr_un sock_un;
484
#endif
485
        struct sockaddr_in sock_in;
486
        char buff[256];
487

    
488
        ret = -1;
489
        if (slirp_socket_passwd) {
490
                s = socket(AF_INET, SOCK_STREAM, 0);
491
                if (s < 0)
492
                   slirp_exit(1);
493
                sock_in.sin_family = AF_INET;
494
                sock_in.sin_addr.s_addr = slirp_socket_addr;
495
                sock_in.sin_port = htons(slirp_socket_port);
496
                if (connect(s, (struct sockaddr *)&sock_in, sizeof(sock_in)) != 0)
497
                   slirp_exit(1); /* just exit...*/
498
                sprintf(buff, "kill %s:%d", slirp_socket_passwd, slirp_socket_unit);
499
                write(s, buff, strlen(buff)+1);
500
        }
501
#ifndef NO_UNIX_SOCKETS
502
          else {
503
                s = socket(AF_UNIX, SOCK_STREAM, 0);
504
                if (s < 0)
505
                   slirp_exit(1);
506
                sock_un.sun_family = AF_UNIX;
507
                strcpy(sock_un.sun_path, socket_path);
508
                if (connect(s, (struct sockaddr *)&sock_un,
509
                              sizeof(sock_un.sun_family) + sizeof(sock_un.sun_path)) != 0)
510
                   slirp_exit(1);
511
                sprintf(buff, "kill none:%d", slirp_socket_unit);
512
                write(s, buff, strlen(buff)+1);
513
        }
514
#endif
515
        slirp_exit(0);
516
}
517

    
518

    
519
void
520
snooze()
521
{
522
        sigset_t s;
523
        int i;
524

    
525
        /* Don't need our data anymore */
526
        /* XXX This makes SunOS barf */
527
/*        brk(0); */
528

    
529
        /* Close all fd's */
530
        for (i = 255; i >= 0; i--)
531
           close(i);
532

    
533
        signal(SIGQUIT, slirp_exit);
534
        signal(SIGHUP, snooze_hup);
535
        sigemptyset(&s);
536

    
537
        /* Wait for any signal */
538
        sigsuspend(&s);
539

    
540
        /* Just in case ... */
541
        exit(255);
542
}
543

    
544
void
545
relay(s)
546
        int s;
547
{
548
        char buf[8192];
549
        int n;
550
        fd_set readfds;
551
        struct ttys *ttyp;
552

    
553
        /* Don't need our data anymore */
554
        /* XXX This makes SunOS barf */
555
/*        brk(0); */
556

    
557
        signal(SIGQUIT, slirp_exit);
558
        signal(SIGHUP, slirp_exit);
559
        signal(SIGINT, slirp_exit);
560
        signal(SIGTERM, slirp_exit);
561

    
562
        /* Fudge to get term_raw and term_restore to work */
563
        if (NULL == (ttyp = tty_attach (0, slirp_tty))) {
564
         lprint ("Error: tty_attach failed in misc.c:relay()\r\n");
565
         slirp_exit (1);
566
    }
567
        ttyp->fd = 0;
568
        ttyp->flags |= TTY_CTTY;
569
        term_raw(ttyp);
570

    
571
        while (1) {
572
                FD_ZERO(&readfds);
573

    
574
                FD_SET(0, &readfds);
575
                FD_SET(s, &readfds);
576

    
577
                n = select(s+1, &readfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0);
578

    
579
                if (n <= 0)
580
                   slirp_exit(0);
581

    
582
                if (FD_ISSET(0, &readfds)) {
583
                        n = read(0, buf, 8192);
584
                        if (n <= 0)
585
                           slirp_exit(0);
586
                        n = writen(s, buf, n);
587
                        if (n <= 0)
588
                           slirp_exit(0);
589
                }
590

    
591
                if (FD_ISSET(s, &readfds)) {
592
                        n = read(s, buf, 8192);
593
                        if (n <= 0)
594
                           slirp_exit(0);
595
                        n = writen(0, buf, n);
596
                        if (n <= 0)
597
                           slirp_exit(0);
598
                }
599
        }
600

    
601
        /* Just in case.... */
602
        exit(1);
603
}
604
#endif
605

    
606
#ifdef CONFIG_QEMU
607
void lprint(const char *format, ...)
608
{
609
    va_list args;
610

    
611
    va_start(args, format);
612
    term_vprintf(format, args);
613
    va_end(args);
614
}
615
#else
616
int (*lprint_print) _P((void *, const char *, va_list));
617
char *lprint_ptr, *lprint_ptr2, **lprint_arg;
618

    
619
void
620
#ifdef __STDC__
621
lprint(const char *format, ...)
622
#else
623
lprint(va_alist) va_dcl
624
#endif
625
{
626
        va_list args;
627

    
628
#ifdef __STDC__
629
        va_start(args, format);
630
#else
631
        char *format;
632
        va_start(args);
633
        format = va_arg(args, char *);
634
#endif
635
#if 0
636
        /* If we're printing to an sbuf, make sure there's enough room */
637
        /* XXX +100? */
638
        if (lprint_sb) {
639
                if ((lprint_ptr - lprint_sb->sb_wptr) >=
640
                    (lprint_sb->sb_datalen - (strlen(format) + 100))) {
641
                        int deltaw = lprint_sb->sb_wptr - lprint_sb->sb_data;
642
                        int deltar = lprint_sb->sb_rptr - lprint_sb->sb_data;
643
                        int deltap = lprint_ptr -         lprint_sb->sb_data;
644

645
                        lprint_sb->sb_data = (char *)realloc(lprint_sb->sb_data,
646
                                                             lprint_sb->sb_datalen + TCP_SNDSPACE);
647

648
                        /* Adjust all values */
649
                        lprint_sb->sb_wptr = lprint_sb->sb_data + deltaw;
650
                        lprint_sb->sb_rptr = lprint_sb->sb_data + deltar;
651
                        lprint_ptr =         lprint_sb->sb_data + deltap;
652

653
                        lprint_sb->sb_datalen += TCP_SNDSPACE;
654
                }
655
        }
656
#endif
657
        if (lprint_print)
658
           lprint_ptr += (*lprint_print)(*lprint_arg, format, args);
659

    
660
        /* Check if they want output to be logged to file as well */
661
        if (lfd) {
662
                /*
663
                 * Remove \r's
664
                 * otherwise you'll get ^M all over the file
665
                 */
666
                int len = strlen(format);
667
                char *bptr1, *bptr2;
668

    
669
                bptr1 = bptr2 = strdup(format);
670

    
671
                while (len--) {
672
                        if (*bptr1 == '\r')
673
                           memcpy(bptr1, bptr1+1, len+1);
674
                        else
675
                           bptr1++;
676
                }
677
                vfprintf(lfd, bptr2, args);
678
                free(bptr2);
679
        }
680
        va_end(args);
681
}
682

    
683
void
684
add_emu(buff)
685
        char *buff;
686
{
687
        u_int lport, fport;
688
        u_int8_t tos = 0, emu = 0;
689
        char buff1[256], buff2[256], buff4[128];
690
        char *buff3 = buff4;
691
        struct emu_t *emup;
692
        struct socket *so;
693

    
694
        if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) {
695
                lprint("Error: Bad arguments\r\n");
696
                return;
697
        }
698

    
699
        if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) {
700
                lport = 0;
701
                if (sscanf(buff1, "%d", &fport) != 1) {
702
                        lprint("Error: Bad first argument\r\n");
703
                        return;
704
                }
705
        }
706

    
707
        if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) {
708
                buff3 = 0;
709
                if (sscanf(buff2, "%256s", buff1) != 1) {
710
                        lprint("Error: Bad second argument\r\n");
711
                        return;
712
                }
713
        }
714

    
715
        if (buff3) {
716
                if (strcmp(buff3, "lowdelay") == 0)
717
                   tos = IPTOS_LOWDELAY;
718
                else if (strcmp(buff3, "throughput") == 0)
719
                   tos = IPTOS_THROUGHPUT;
720
                else {
721
                        lprint("Error: Expecting \"lowdelay\"/\"throughput\"\r\n");
722
                        return;
723
                }
724
        }
725

    
726
        if (strcmp(buff1, "ftp") == 0)
727
           emu = EMU_FTP;
728
        else if (strcmp(buff1, "irc") == 0)
729
           emu = EMU_IRC;
730
        else if (strcmp(buff1, "none") == 0)
731
           emu = EMU_NONE; /* ie: no emulation */
732
        else {
733
                lprint("Error: Unknown service\r\n");
734
                return;
735
        }
736

    
737
        /* First, check that it isn't already emulated */
738
        for (emup = tcpemu; emup; emup = emup->next) {
739
                if (emup->lport == lport && emup->fport == fport) {
740
                        lprint("Error: port already emulated\r\n");
741
                        return;
742
                }
743
        }
744

    
745
        /* link it */
746
        emup = (struct emu_t *)malloc(sizeof (struct emu_t));
747
        emup->lport = (u_int16_t)lport;
748
        emup->fport = (u_int16_t)fport;
749
        emup->tos = tos;
750
        emup->emu = emu;
751
        emup->next = tcpemu;
752
        tcpemu = emup;
753

    
754
        /* And finally, mark all current sessions, if any, as being emulated */
755
        for (so = tcb.so_next; so != &tcb; so = so->so_next) {
756
                if ((lport && lport == ntohs(so->so_lport)) ||
757
                    (fport && fport == ntohs(so->so_fport))) {
758
                        if (emu)
759
                           so->so_emu = emu;
760
                        if (tos)
761
                           so->so_iptos = tos;
762
                }
763
        }
764

    
765
        lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport);
766
}
767
#endif
768

    
769
#ifdef BAD_SPRINTF
770

    
771
#undef vsprintf
772
#undef sprintf
773

    
774
/*
775
 * Some BSD-derived systems have a sprintf which returns char *
776
 */
777

    
778
int
779
vsprintf_len(string, format, args)
780
        char *string;
781
        const char *format;
782
        va_list args;
783
{
784
        vsprintf(string, format, args);
785
        return strlen(string);
786
}
787

    
788
int
789
#ifdef __STDC__
790
sprintf_len(char *string, const char *format, ...)
791
#else
792
sprintf_len(va_alist) va_dcl
793
#endif
794
{
795
        va_list args;
796
#ifdef __STDC__
797
        va_start(args, format);
798
#else
799
        char *string;
800
        char *format;
801
        va_start(args);
802
        string = va_arg(args, char *);
803
        format = va_arg(args, char *);
804
#endif
805
        vsprintf(string, format, args);
806
        return strlen(string);
807
}
808

    
809
#endif
810

    
811
void
812
u_sleep(usec)
813
        int usec;
814
{
815
        struct timeval t;
816
        fd_set fdset;
817

    
818
        FD_ZERO(&fdset);
819

    
820
        t.tv_sec = 0;
821
        t.tv_usec = usec * 1000;
822

    
823
        select(0, &fdset, &fdset, &fdset, &t);
824
}
825

    
826
/*
827
 * Set fd blocking and non-blocking
828
 */
829

    
830
void
831
fd_nonblock(fd)
832
        int fd;
833
{
834
#ifdef FIONBIO
835
        int opt = 1;
836

    
837
        ioctlsocket(fd, FIONBIO, &opt);
838
#else
839
        int opt;
840

    
841
        opt = fcntl(fd, F_GETFL, 0);
842
        opt |= O_NONBLOCK;
843
        fcntl(fd, F_SETFL, opt);
844
#endif
845
}
846

    
847
void
848
fd_block(fd)
849
        int fd;
850
{
851
#ifdef FIONBIO
852
        int opt = 0;
853

    
854
        ioctlsocket(fd, FIONBIO, &opt);
855
#else
856
        int opt;
857

    
858
        opt = fcntl(fd, F_GETFL, 0);
859
        opt &= ~O_NONBLOCK;
860
        fcntl(fd, F_SETFL, opt);
861
#endif
862
}
863

    
864

    
865
#if 0
866
/*
867
 * invoke RSH
868
 */
869
int
870
rsh_exec(so,ns, user, host, args)
871
        struct socket *so;
872
        struct socket *ns;
873
        char *user;
874
        char *host;
875
        char *args;
876
{
877
        int fd[2];
878
        int fd0[2];
879
        int s;
880
        char buff[256];
881

882
        DEBUG_CALL("rsh_exec");
883
        DEBUG_ARG("so = %lx", (long)so);
884

885
        if (pipe(fd)<0) {
886
          lprint("Error: pipe failed: %s\n", strerror(errno));
887
          return 0;
888
        }
889
/* #ifdef HAVE_SOCKETPAIR */
890
#if 1
891
        if (socketpair(PF_UNIX,SOCK_STREAM,0, fd0) == -1) {
892
          close(fd[0]);
893
          close(fd[1]);
894
          lprint("Error: openpty failed: %s\n", strerror(errno));
895
          return 0;
896
        }
897
#else
898
        if (slirp_openpty(&fd0[0], &fd0[1]) == -1) {
899
          close(fd[0]);
900
          close(fd[1]);
901
          lprint("Error: openpty failed: %s\n", strerror(errno));
902
          return 0;
903
        }
904
#endif
905

    
906
        switch(fork()) {
907
         case -1:
908
           lprint("Error: fork failed: %s\n", strerror(errno));
909
           close(fd[0]);
910
           close(fd[1]);
911
           close(fd0[0]);
912
           close(fd0[1]);
913
           return 0;
914

    
915
         case 0:
916
           close(fd[0]);
917
           close(fd0[0]);
918

    
919
                /* Set the DISPLAY */
920
           if (x_port >= 0) {
921
#ifdef HAVE_SETENV
922
             sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
923
             setenv("DISPLAY", buff, 1);
924
#else
925
             sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
926
             putenv(buff);
927
#endif
928
           }
929

    
930
           dup2(fd0[1], 0);
931
           dup2(fd0[1], 1);
932
           dup2(fd[1], 2);
933
           for (s = 3; s <= 255; s++)
934
             close(s);
935

    
936
           execlp("rsh","rsh","-l", user, host, args, NULL);
937

    
938
           /* Ooops, failed, let's tell the user why */
939

    
940
           sprintf(buff, "Error: execlp of %s failed: %s\n",
941
                   "rsh", strerror(errno));
942
           write(2, buff, strlen(buff)+1);
943
           close(0); close(1); close(2); /* XXX */
944
           exit(1);
945

    
946
        default:
947
          close(fd[1]);
948
          close(fd0[1]);
949
          ns->s=fd[0];
950
          so->s=fd0[0];
951

    
952
          return 1;
953
        }
954
}
955
#endif