Statistics
| Branch: | Revision:

root / slirp / misc.c @ 5fafdf24

History | View | Annotate | Download (19 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
int (*lprint_print) _P((void *, const char *, va_list));
607
char *lprint_ptr, *lprint_ptr2, **lprint_arg;
608

    
609
void
610
#ifdef __STDC__
611
lprint(const char *format, ...)
612
#else
613
lprint(va_alist) va_dcl
614
#endif
615
{
616
        va_list args;
617
       
618
#ifdef __STDC__
619
        va_start(args, format);
620
#else
621
        char *format;
622
        va_start(args);
623
        format = va_arg(args, char *);
624
#endif
625
#if 0
626
        /* If we're printing to an sbuf, make sure there's enough room */
627
        /* XXX +100? */
628
        if (lprint_sb) {
629
                if ((lprint_ptr - lprint_sb->sb_wptr) >=
630
                    (lprint_sb->sb_datalen - (strlen(format) + 100))) {
631
                        int deltaw = lprint_sb->sb_wptr - lprint_sb->sb_data;
632
                        int deltar = lprint_sb->sb_rptr - lprint_sb->sb_data;
633
                        int deltap = lprint_ptr -         lprint_sb->sb_data;
634
                                               
635
                        lprint_sb->sb_data = (char *)realloc(lprint_sb->sb_data,
636
                                                             lprint_sb->sb_datalen + TCP_SNDSPACE);
637
                
638
                        /* Adjust all values */
639
                        lprint_sb->sb_wptr = lprint_sb->sb_data + deltaw;
640
                        lprint_sb->sb_rptr = lprint_sb->sb_data + deltar;
641
                        lprint_ptr =         lprint_sb->sb_data + deltap;
642
                
643
                        lprint_sb->sb_datalen += TCP_SNDSPACE;
644
                }
645
        }
646
#endif
647
        if (lprint_print)
648
           lprint_ptr += (*lprint_print)(*lprint_arg, format, args);
649

    
650
        /* Check if they want output to be logged to file as well */
651
        if (lfd) {
652
                /*
653
                 * Remove \r's
654
                 * otherwise you'll get ^M all over the file
655
                 */
656
                int len = strlen(format);
657
                char *bptr1, *bptr2;
658
        
659
                bptr1 = bptr2 = strdup(format);
660
        
661
                while (len--) {
662
                        if (*bptr1 == '\r')
663
                           memcpy(bptr1, bptr1+1, len+1);
664
                        else
665
                           bptr1++;
666
                }
667
                vfprintf(lfd, bptr2, args);
668
                free(bptr2);
669
        }
670
        va_end(args);
671
}
672

    
673
void
674
add_emu(buff)
675
        char *buff;
676
{
677
        u_int lport, fport;
678
        u_int8_t tos = 0, emu = 0;
679
        char buff1[256], buff2[256], buff4[128];
680
        char *buff3 = buff4;
681
        struct emu_t *emup;
682
        struct socket *so;
683

    
684
        if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) {
685
                lprint("Error: Bad arguments\r\n");
686
                return;
687
        }
688

    
689
        if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) {
690
                lport = 0;
691
                if (sscanf(buff1, "%d", &fport) != 1) {
692
                        lprint("Error: Bad first argument\r\n");
693
                        return;
694
                }
695
        }
696

    
697
        if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) {
698
                buff3 = 0;
699
                if (sscanf(buff2, "%256s", buff1) != 1) {
700
                        lprint("Error: Bad second argument\r\n");
701
                        return;
702
                }
703
        }
704

    
705
        if (buff3) {
706
                if (strcmp(buff3, "lowdelay") == 0)
707
                   tos = IPTOS_LOWDELAY;
708
                else if (strcmp(buff3, "throughput") == 0)
709
                   tos = IPTOS_THROUGHPUT;
710
                else {
711
                        lprint("Error: Expecting \"lowdelay\"/\"throughput\"\r\n");
712
                        return;
713
                }
714
        }
715

    
716
        if (strcmp(buff1, "ftp") == 0)
717
           emu = EMU_FTP;
718
        else if (strcmp(buff1, "irc") == 0)
719
           emu = EMU_IRC;
720
        else if (strcmp(buff1, "none") == 0)
721
           emu = EMU_NONE; /* ie: no emulation */
722
        else {
723
                lprint("Error: Unknown service\r\n");
724
                return;
725
        }
726

    
727
        /* First, check that it isn't already emulated */
728
        for (emup = tcpemu; emup; emup = emup->next) {
729
                if (emup->lport == lport && emup->fport == fport) {
730
                        lprint("Error: port already emulated\r\n");
731
                        return;
732
                }
733
        }
734

    
735
        /* link it */
736
        emup = (struct emu_t *)malloc(sizeof (struct emu_t));
737
        emup->lport = (u_int16_t)lport;
738
        emup->fport = (u_int16_t)fport;
739
        emup->tos = tos;
740
        emup->emu = emu;
741
        emup->next = tcpemu;
742
        tcpemu = emup;
743

    
744
        /* And finally, mark all current sessions, if any, as being emulated */
745
        for (so = tcb.so_next; so != &tcb; so = so->so_next) {
746
                if ((lport && lport == ntohs(so->so_lport)) ||
747
                    (fport && fport == ntohs(so->so_fport))) {
748
                        if (emu)
749
                           so->so_emu = emu;
750
                        if (tos)
751
                           so->so_iptos = tos;
752
                }
753
        }
754

    
755
        lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport);
756
}
757

    
758
#ifdef BAD_SPRINTF
759

    
760
#undef vsprintf
761
#undef sprintf
762

    
763
/*
764
 * Some BSD-derived systems have a sprintf which returns char *
765
 */
766

    
767
int
768
vsprintf_len(string, format, args)
769
        char *string;
770
        const char *format;
771
        va_list args;
772
{
773
        vsprintf(string, format, args);
774
        return strlen(string);
775
}
776

    
777
int
778
#ifdef __STDC__
779
sprintf_len(char *string, const char *format, ...)
780
#else
781
sprintf_len(va_alist) va_dcl
782
#endif
783
{
784
        va_list args;
785
#ifdef __STDC__
786
        va_start(args, format);
787
#else
788
        char *string;
789
        char *format;
790
        va_start(args);
791
        string = va_arg(args, char *);
792
        format = va_arg(args, char *);
793
#endif
794
        vsprintf(string, format, args);
795
        return strlen(string);
796
}
797

    
798
#endif
799

    
800
void
801
u_sleep(usec)
802
        int usec;
803
{
804
        struct timeval t;
805
        fd_set fdset;
806

    
807
        FD_ZERO(&fdset);
808

    
809
        t.tv_sec = 0;
810
        t.tv_usec = usec * 1000;
811

    
812
        select(0, &fdset, &fdset, &fdset, &t);
813
}
814

    
815
/*
816
 * Set fd blocking and non-blocking
817
 */
818

    
819
void
820
fd_nonblock(fd)
821
        int fd;
822
{
823
#ifdef FIONBIO
824
        int opt = 1;
825

    
826
        ioctlsocket(fd, FIONBIO, &opt);
827
#else
828
        int opt;
829

    
830
        opt = fcntl(fd, F_GETFL, 0);
831
        opt |= O_NONBLOCK;
832
        fcntl(fd, F_SETFL, opt);
833
#endif
834
}
835

    
836
void
837
fd_block(fd)
838
        int fd;
839
{
840
#ifdef FIONBIO
841
        int opt = 0;
842

    
843
        ioctlsocket(fd, FIONBIO, &opt);
844
#else
845
        int opt;
846

    
847
        opt = fcntl(fd, F_GETFL, 0);
848
        opt &= ~O_NONBLOCK;
849
        fcntl(fd, F_SETFL, opt);
850
#endif
851
}
852

    
853

    
854
#if 0
855
/*
856
 * invoke RSH
857
 */
858
int
859
rsh_exec(so,ns, user, host, args)
860
        struct socket *so;
861
        struct socket *ns;
862
        char *user;
863
        char *host;
864
        char *args;
865
{
866
        int fd[2];
867
        int fd0[2];
868
        int s;
869
        char buff[256];
870

871
        DEBUG_CALL("rsh_exec");
872
        DEBUG_ARG("so = %lx", (long)so);
873

874
        if (pipe(fd)<0) {
875
          lprint("Error: pipe failed: %s\n", strerror(errno));
876
          return 0;
877
        }
878
/* #ifdef HAVE_SOCKETPAIR */
879
#if 1
880
        if (socketpair(PF_UNIX,SOCK_STREAM,0, fd0) == -1) {
881
          close(fd[0]);
882
          close(fd[1]);
883
          lprint("Error: openpty failed: %s\n", strerror(errno));
884
          return 0;
885
        }
886
#else
887
        if (slirp_openpty(&fd0[0], &fd0[1]) == -1) {
888
          close(fd[0]);
889
          close(fd[1]);
890
          lprint("Error: openpty failed: %s\n", strerror(errno));
891
          return 0;
892
        }
893
#endif
894

    
895
        switch(fork()) {
896
         case -1:
897
           lprint("Error: fork failed: %s\n", strerror(errno));
898
           close(fd[0]);
899
           close(fd[1]);
900
           close(fd0[0]);
901
           close(fd0[1]);
902
           return 0;
903
          
904
         case 0:
905
           close(fd[0]);
906
           close(fd0[0]);
907
          
908
                /* Set the DISPLAY */
909
           if (x_port >= 0) {
910
#ifdef HAVE_SETENV
911
             sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
912
             setenv("DISPLAY", buff, 1);
913
#else
914
             sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
915
             putenv(buff);
916
#endif
917
           }
918
          
919
           dup2(fd0[1], 0);
920
           dup2(fd0[1], 1);
921
           dup2(fd[1], 2);
922
           for (s = 3; s <= 255; s++)
923
             close(s);
924
          
925
           execlp("rsh","rsh","-l", user, host, args, NULL);
926
          
927
           /* Ooops, failed, let's tell the user why */
928
          
929
           sprintf(buff, "Error: execlp of %s failed: %s\n",
930
                   "rsh", strerror(errno));
931
           write(2, buff, strlen(buff)+1);
932
           close(0); close(1); close(2); /* XXX */
933
           exit(1);
934
          
935
        default:
936
          close(fd[1]);
937
          close(fd0[1]);
938
          ns->s=fd[0];
939
          so->s=fd0[0];
940
         
941
          return 1;
942
        }
943
}
944
#endif