Statistics
| Branch: | Revision:

root / slirp / misc.c @ 977d5710

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;
92
        
93
        if (gethostname(buff,256) < 0)
94
           return;
95
        
96
        if ((he = gethostbyname(buff)) == NULL)
97
           return;
98
        
99
        our_addr = *(struct in_addr *)he->h_addr;
100
}
101

    
102
#if SIZEOF_CHAR_P == 8
103

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

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

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

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

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

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

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

    
164
/* #endif */
165

    
166

    
167
int
168
add_exec(ex_ptr, do_pty, exec, addr, port)
169
        struct ex_list **ex_ptr;
170
        int do_pty;
171
        char *exec;
172
        int addr;
173
        int port;
174
{
175
        struct ex_list *tmp_ptr;
176
        
177
        /* First, check if the port is "bound" */
178
        for (tmp_ptr = *ex_ptr; tmp_ptr; tmp_ptr = tmp_ptr->ex_next) {
179
                if (port == tmp_ptr->ex_fport && addr == tmp_ptr->ex_addr)
180
                   return -1;
181
        }
182
        
183
        tmp_ptr = *ex_ptr;
184
        *ex_ptr = (struct ex_list *)malloc(sizeof(struct ex_list));
185
        (*ex_ptr)->ex_fport = port;
186
        (*ex_ptr)->ex_addr = addr;
187
        (*ex_ptr)->ex_pty = do_pty;
188
        (*ex_ptr)->ex_exec = strdup(exec);
189
        (*ex_ptr)->ex_next = tmp_ptr;
190
        return 0;
191
}
192

    
193
#ifndef HAVE_STRERROR
194

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

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

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

    
212
#endif
213

    
214

    
215
#ifdef _WIN32
216

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

    
227
#else
228

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

    
235
#ifdef HAVE_GRANTPT
236
        char *ptr;
237
        
238
        if ((master = open("/dev/ptmx", O_RDWR)) < 0 ||
239
            grantpt(master) < 0 ||
240
            unlockpt(master) < 0 ||
241
            (ptr = ptsname(master)) == NULL)  {
242
                close(master);
243
                return -1;
244
        }
245
        
246
        if ((slave = open(ptr, O_RDWR)) < 0 ||
247
            ioctl(slave, I_PUSH, "ptem") < 0 ||
248
            ioctl(slave, I_PUSH, "ldterm") < 0 ||
249
            ioctl(slave, I_PUSH, "ttcompat") < 0) {
250
                close(master);
251
                close(slave);
252
                return -1;
253
        }
254
        
255
        *amaster = master;
256
        *aslave = slave;
257
        return 0;
258
        
259
#else
260
        
261
        static char line[] = "/dev/ptyXX";
262
        register const char *cp1, *cp2;
263
        
264
        for (cp1 = "pqrsPQRS"; *cp1; cp1++) {
265
                line[8] = *cp1;
266
                for (cp2 = "0123456789abcdefghijklmnopqrstuv"; *cp2; cp2++) {
267
                        line[9] = *cp2;
268
                        if ((master = open(line, O_RDWR, 0)) == -1) {
269
                                if (errno == ENOENT)
270
                                   return (-1);    /* out of ptys */
271
                        } else {
272
                                line[5] = 't';
273
                                /* These will fail */
274
                                (void) chown(line, getuid(), 0);
275
                                (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
276
#ifdef HAVE_REVOKE
277
                                (void) revoke(line);
278
#endif
279
                                if ((slave = open(line, O_RDWR, 0)) != -1) {
280
                                        *amaster = master;
281
                                        *aslave = slave;
282
                                        return 0;
283
                                }
284
                                (void) close(master);
285
                                line[5] = 'p';
286
                        }
287
                }
288
        }
289
        errno = ENOENT; /* out of ptys */
290
        return (-1);
291
#endif
292
}
293

    
294
/*
295
 * XXX This is ugly
296
 * We create and bind a socket, then fork off to another
297
 * process, which connects to this socket, after which we
298
 * exec the wanted program.  If something (strange) happens,
299
 * the accept() call could block us forever.
300
 * 
301
 * do_pty = 0   Fork/exec inetd style
302
 * do_pty = 1   Fork/exec using slirp.telnetd
303
 * do_ptr = 2   Fork/exec using pty
304
 */
305
int
306
fork_exec(so, ex, do_pty)
307
        struct socket *so;
308
        char *ex;
309
        int do_pty;
310
{
311
        int s;
312
        struct sockaddr_in addr;
313
        int addrlen = sizeof(addr);
314
        int opt;
315
        int master;
316
        char *argv[256];
317
#if 0
318
        char buff[256];
319
#endif
320
        /* don't want to clobber the original */
321
        char *bptr;
322
        char *curarg;
323
        int c, i, ret;
324
        
325
        DEBUG_CALL("fork_exec");
326
        DEBUG_ARG("so = %lx", (long)so);
327
        DEBUG_ARG("ex = %lx", (long)ex);
328
        DEBUG_ARG("do_pty = %lx", (long)do_pty);
329
        
330
        if (do_pty == 2) {
331
                if (slirp_openpty(&master, &s) == -1) {
332
                        lprint("Error: openpty failed: %s\n", strerror(errno));
333
                        return 0;
334
                }
335
        } else {
336
                addr.sin_family = AF_INET;
337
                addr.sin_port = 0;
338
                addr.sin_addr.s_addr = INADDR_ANY;
339
                
340
                if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ||
341
                    bind(s, (struct sockaddr *)&addr, addrlen) < 0 ||
342
                    listen(s, 1) < 0) {
343
                        lprint("Error: inet socket: %s\n", strerror(errno));
344
                        closesocket(s);
345
                        
346
                        return 0;
347
                }
348
        }
349
        
350
        switch(fork()) {
351
         case -1:
352
                lprint("Error: fork failed: %s\n", strerror(errno));
353
                close(s);
354
                if (do_pty == 2)
355
                   close(master);
356
                return 0;
357
                
358
         case 0:
359
                /* Set the DISPLAY */
360
                if (do_pty == 2) {
361
                        (void) close(master);
362
#ifdef TIOCSCTTY /* XXXXX */
363
                        (void) setsid();
364
                        ioctl(s, TIOCSCTTY, (char *)NULL);
365
#endif
366
                } else {
367
                        getsockname(s, (struct sockaddr *)&addr, &addrlen);
368
                        close(s);
369
                        /*
370
                         * Connect to the socket
371
                         * XXX If any of these fail, we're in trouble!
372
                          */
373
                        s = socket(AF_INET, SOCK_STREAM, 0);
374
                        addr.sin_addr = loopback_addr;
375
                        do {
376
                            ret = connect(s, (struct sockaddr *)&addr, addrlen);
377
                        } while (ret < 0 && errno == EINTR);
378
                }
379
                
380
#if 0
381
                if (x_port >= 0) {
382
#ifdef HAVE_SETENV
383
                        sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
384
                        setenv("DISPLAY", buff, 1);
385
#else
386
                        sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
387
                        putenv(buff);
388
#endif
389
                }
390
#endif        
391
                dup2(s, 0);
392
                dup2(s, 1);
393
                dup2(s, 2);
394
                for (s = 3; s <= 255; s++)
395
                   close(s);
396
                
397
                i = 0;
398
                bptr = strdup(ex); /* No need to free() this */
399
                if (do_pty == 1) {
400
                        /* Setup "slirp.telnetd -x" */
401
                        argv[i++] = "slirp.telnetd";
402
                        argv[i++] = "-x";
403
                        argv[i++] = bptr;
404
                } else
405
                   do {
406
                        /* Change the string into argv[] */
407
                        curarg = bptr;
408
                        while (*bptr != ' ' && *bptr != (char)0)
409
                           bptr++;
410
                        c = *bptr;
411
                        *bptr++ = (char)0;
412
                        argv[i++] = strdup(curarg);
413
                   } while (c);
414
                
415
                argv[i] = 0;
416
                execvp(argv[0], argv);
417
                
418
                /* Ooops, failed, let's tell the user why */
419
                  {
420
                          char buff[256];
421
                          
422
                          sprintf(buff, "Error: execvp of %s failed: %s\n", 
423
                                  argv[0], strerror(errno));
424
                          write(2, buff, strlen(buff)+1);
425
                  }
426
                close(0); close(1); close(2); /* XXX */
427
                exit(1);
428
                
429
         default:
430
                if (do_pty == 2) {
431
                        close(s);
432
                        so->s = master;
433
                } else {
434
                        /*
435
                         * XXX this could block us...
436
                         * XXX Should set a timer here, and if accept() doesn't
437
                          * return after X seconds, declare it a failure
438
                          * The only reason this will block forever is if socket()
439
                          * of connect() fail in the child process
440
                          */
441
                        do {
442
                            so->s = accept(s, (struct sockaddr *)&addr, &addrlen);
443
                        } while (so->s < 0 && errno == EINTR);
444
                        closesocket(s);
445
                        opt = 1;
446
                        setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));
447
                        opt = 1;
448
                        setsockopt(so->s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
449
                }
450
                fd_nonblock(so->s);
451
                
452
                /* Append the telnet options now */
453
                if (so->so_m != 0 && do_pty == 1)  {
454
                        sbappend(so, so->so_m);
455
                        so->so_m = 0;
456
                }
457
                
458
                return 1;
459
        }
460
}
461
#endif
462

    
463
#ifndef HAVE_STRDUP
464
char *
465
strdup(str)
466
        const char *str;
467
{
468
        char *bptr;
469
        
470
        bptr = (char *)malloc(strlen(str)+1);
471
        strcpy(bptr, str);
472
        
473
        return bptr;
474
}
475
#endif
476

    
477
#if 0
478
void
479
snooze_hup(num)
480
        int num;
481
{
482
        int s, ret;
483
#ifndef NO_UNIX_SOCKETS
484
        struct sockaddr_un sock_un;
485
#endif
486
        struct sockaddr_in sock_in;
487
        char buff[256];
488
        
489
        ret = -1;
490
        if (slirp_socket_passwd) {
491
                s = socket(AF_INET, SOCK_STREAM, 0);
492
                if (s < 0)
493
                   slirp_exit(1);
494
                sock_in.sin_family = AF_INET;
495
                sock_in.sin_addr.s_addr = slirp_socket_addr;
496
                sock_in.sin_port = htons(slirp_socket_port);
497
                if (connect(s, (struct sockaddr *)&sock_in, sizeof(sock_in)) != 0)
498
                   slirp_exit(1); /* just exit...*/
499
                sprintf(buff, "kill %s:%d", slirp_socket_passwd, slirp_socket_unit);
500
                write(s, buff, strlen(buff)+1);
501
        }
502
#ifndef NO_UNIX_SOCKETS
503
          else {
504
                s = socket(AF_UNIX, SOCK_STREAM, 0);
505
                if (s < 0)
506
                   slirp_exit(1);
507
                sock_un.sun_family = AF_UNIX;
508
                strcpy(sock_un.sun_path, socket_path);
509
                if (connect(s, (struct sockaddr *)&sock_un,
510
                              sizeof(sock_un.sun_family) + sizeof(sock_un.sun_path)) != 0)
511
                   slirp_exit(1);
512
                sprintf(buff, "kill none:%d", slirp_socket_unit);
513
                write(s, buff, strlen(buff)+1);
514
        }
515
#endif
516
        slirp_exit(0);
517
}
518
        
519
        
520
void
521
snooze()
522
{
523
        sigset_t s;
524
        int i;
525
        
526
        /* Don't need our data anymore */
527
        /* XXX This makes SunOS barf */
528
/*        brk(0); */
529
        
530
        /* Close all fd's */
531
        for (i = 255; i >= 0; i--)
532
           close(i);
533
        
534
        signal(SIGQUIT, slirp_exit);
535
        signal(SIGHUP, snooze_hup);
536
        sigemptyset(&s);
537
        
538
        /* Wait for any signal */
539
        sigsuspend(&s);
540
        
541
        /* Just in case ... */
542
        exit(255);
543
}
544

    
545
void
546
relay(s)
547
        int s;
548
{
549
        char buf[8192];
550
        int n;
551
        fd_set readfds;
552
        struct ttys *ttyp;
553
        
554
        /* Don't need our data anymore */
555
        /* XXX This makes SunOS barf */
556
/*        brk(0); */
557
        
558
        signal(SIGQUIT, slirp_exit);
559
        signal(SIGHUP, slirp_exit);
560
        signal(SIGINT, slirp_exit);
561
        signal(SIGTERM, slirp_exit);
562
        
563
        /* Fudge to get term_raw and term_restore to work */
564
        if (NULL == (ttyp = tty_attach (0, slirp_tty))) {
565
         lprint ("Error: tty_attach failed in misc.c:relay()\r\n");
566
         slirp_exit (1);
567
    }
568
        ttyp->fd = 0;
569
        ttyp->flags |= TTY_CTTY;
570
        term_raw(ttyp);
571
        
572
        while (1) {
573
                FD_ZERO(&readfds);
574
                
575
                FD_SET(0, &readfds);
576
                FD_SET(s, &readfds);
577
                
578
                n = select(s+1, &readfds, (fd_set *)0, (fd_set *)0, (struct timeval *)0);
579
                
580
                if (n <= 0)
581
                   slirp_exit(0);
582
                
583
                if (FD_ISSET(0, &readfds)) {
584
                        n = read(0, buf, 8192);
585
                        if (n <= 0)
586
                           slirp_exit(0);
587
                        n = writen(s, buf, n);
588
                        if (n <= 0)
589
                           slirp_exit(0);
590
                }
591
                
592
                if (FD_ISSET(s, &readfds)) {
593
                        n = read(s, buf, 8192);
594
                        if (n <= 0)
595
                           slirp_exit(0);
596
                        n = writen(0, buf, n);
597
                        if (n <= 0)
598
                           slirp_exit(0);
599
                }
600
        }
601
        
602
        /* Just in case.... */
603
        exit(1);
604
}
605
#endif
606

    
607
int (*lprint_print) _P((void *, const char *, va_list));
608
char *lprint_ptr, *lprint_ptr2, **lprint_arg;
609

    
610
void
611
#ifdef __STDC__
612
lprint(const char *format, ...)
613
#else
614
lprint(va_alist) va_dcl
615
#endif
616
{
617
        va_list args;
618
        
619
#ifdef __STDC__
620
        va_start(args, format);
621
#else
622
        char *format;
623
        va_start(args);
624
        format = va_arg(args, char *);
625
#endif
626
#if 0
627
        /* If we're printing to an sbuf, make sure there's enough room */
628
        /* XXX +100? */
629
        if (lprint_sb) {
630
                if ((lprint_ptr - lprint_sb->sb_wptr) >=
631
                    (lprint_sb->sb_datalen - (strlen(format) + 100))) {
632
                        int deltaw = lprint_sb->sb_wptr - lprint_sb->sb_data;
633
                        int deltar = lprint_sb->sb_rptr - lprint_sb->sb_data;
634
                        int deltap = lprint_ptr -         lprint_sb->sb_data;
635
                                                
636
                        lprint_sb->sb_data = (char *)realloc(lprint_sb->sb_data,
637
                                                             lprint_sb->sb_datalen + TCP_SNDSPACE);
638
                        
639
                        /* Adjust all values */
640
                        lprint_sb->sb_wptr = lprint_sb->sb_data + deltaw;
641
                        lprint_sb->sb_rptr = lprint_sb->sb_data + deltar;
642
                        lprint_ptr =         lprint_sb->sb_data + deltap;
643
                        
644
                        lprint_sb->sb_datalen += TCP_SNDSPACE;
645
                }
646
        }
647
#endif        
648
        if (lprint_print)
649
           lprint_ptr += (*lprint_print)(*lprint_arg, format, args);
650
        
651
        /* Check if they want output to be logged to file as well */
652
        if (lfd) {
653
                /* 
654
                 * Remove \r's
655
                 * otherwise you'll get ^M all over the file
656
                 */
657
                int len = strlen(format);
658
                char *bptr1, *bptr2;
659
                
660
                bptr1 = bptr2 = strdup(format);
661
                
662
                while (len--) {
663
                        if (*bptr1 == '\r')
664
                           memcpy(bptr1, bptr1+1, len+1);
665
                        else
666
                           bptr1++;
667
                }
668
                vfprintf(lfd, bptr2, args);
669
                free(bptr2);
670
        }
671
        va_end(args);
672
}
673

    
674
void
675
add_emu(buff)
676
        char *buff;
677
{
678
        u_int lport, fport;
679
        u_int8_t tos = 0, emu = 0;
680
        char buff1[256], buff2[256], buff4[128];
681
        char *buff3 = buff4;
682
        struct emu_t *emup;
683
        struct socket *so;
684
        
685
        if (sscanf(buff, "%256s %256s", buff2, buff1) != 2) {
686
                lprint("Error: Bad arguments\r\n");
687
                return;
688
        }
689
        
690
        if (sscanf(buff1, "%d:%d", &lport, &fport) != 2) {
691
                lport = 0;
692
                if (sscanf(buff1, "%d", &fport) != 1) {
693
                        lprint("Error: Bad first argument\r\n");
694
                        return;
695
                }
696
        }
697
        
698
        if (sscanf(buff2, "%128[^:]:%128s", buff1, buff3) != 2) {
699
                buff3 = 0;
700
                if (sscanf(buff2, "%256s", buff1) != 1) {
701
                        lprint("Error: Bad second argument\r\n");
702
                        return;
703
                }
704
        }
705
        
706
        if (buff3) {
707
                if (strcmp(buff3, "lowdelay") == 0)
708
                   tos = IPTOS_LOWDELAY;
709
                else if (strcmp(buff3, "throughput") == 0)
710
                   tos = IPTOS_THROUGHPUT;
711
                else {
712
                        lprint("Error: Expecting \"lowdelay\"/\"throughput\"\r\n");
713
                        return;
714
                }
715
        }
716
        
717
        if (strcmp(buff1, "ftp") == 0)
718
           emu = EMU_FTP;
719
        else if (strcmp(buff1, "irc") == 0)
720
           emu = EMU_IRC;
721
        else if (strcmp(buff1, "none") == 0)
722
           emu = EMU_NONE; /* ie: no emulation */
723
        else {
724
                lprint("Error: Unknown service\r\n");
725
                return;
726
        }
727
        
728
        /* First, check that it isn't already emulated */
729
        for (emup = tcpemu; emup; emup = emup->next) {
730
                if (emup->lport == lport && emup->fport == fport) {
731
                        lprint("Error: port already emulated\r\n");
732
                        return;
733
                }
734
        }
735
        
736
        /* link it */
737
        emup = (struct emu_t *)malloc(sizeof (struct emu_t));
738
        emup->lport = (u_int16_t)lport;
739
        emup->fport = (u_int16_t)fport;
740
        emup->tos = tos;
741
        emup->emu = emu;
742
        emup->next = tcpemu;
743
        tcpemu = emup;
744
        
745
        /* And finally, mark all current sessions, if any, as being emulated */
746
        for (so = tcb.so_next; so != &tcb; so = so->so_next) {
747
                if ((lport && lport == ntohs(so->so_lport)) ||
748
                    (fport && fport == ntohs(so->so_fport))) {
749
                        if (emu)
750
                           so->so_emu = emu;
751
                        if (tos)
752
                           so->so_iptos = tos;
753
                }
754
        }
755
        
756
        lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport);
757
}
758

    
759
#ifdef BAD_SPRINTF
760

    
761
#undef vsprintf
762
#undef sprintf
763

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

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

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

    
799
#endif
800

    
801
void
802
u_sleep(usec)
803
        int usec;
804
{
805
        struct timeval t;
806
        fd_set fdset;
807
        
808
        FD_ZERO(&fdset);
809
        
810
        t.tv_sec = 0;
811
        t.tv_usec = usec * 1000;
812
        
813
        select(0, &fdset, &fdset, &fdset, &t);
814
}
815

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

    
820
void
821
fd_nonblock(fd)
822
        int fd;
823
{
824
#ifdef FIONBIO
825
        int opt = 1;
826
        
827
        ioctlsocket(fd, FIONBIO, &opt);
828
#else
829
        int opt;
830
        
831
        opt = fcntl(fd, F_GETFL, 0);
832
        opt |= O_NONBLOCK;
833
        fcntl(fd, F_SETFL, opt);
834
#endif
835
}
836

    
837
void
838
fd_block(fd)
839
        int fd;
840
{
841
#ifdef FIONBIO
842
        int opt = 0;
843
        
844
        ioctlsocket(fd, FIONBIO, &opt);
845
#else
846
        int opt;
847
        
848
        opt = fcntl(fd, F_GETFL, 0);
849
        opt &= ~O_NONBLOCK;
850
        fcntl(fd, F_SETFL, opt);
851
#endif
852
}
853

    
854

    
855
#if 0
856
/*
857
 * invoke RSH
858
 */
859
int
860
rsh_exec(so,ns, user, host, args)
861
        struct socket *so;
862
        struct socket *ns;
863
        char *user;
864
        char *host;
865
        char *args;
866
{
867
        int fd[2];
868
        int fd0[2];
869
        int s;
870
        char buff[256];
871
        
872
        DEBUG_CALL("rsh_exec");
873
        DEBUG_ARG("so = %lx", (long)so);
874
        
875
        if (pipe(fd)<0) {
876
          lprint("Error: pipe failed: %s\n", strerror(errno));
877
          return 0;
878
        }
879
/* #ifdef HAVE_SOCKETPAIR */
880
#if 1
881
        if (socketpair(PF_UNIX,SOCK_STREAM,0, fd0) == -1) {
882
          close(fd[0]);
883
          close(fd[1]);
884
          lprint("Error: openpty failed: %s\n", strerror(errno));
885
          return 0;
886
        }
887
#else
888
        if (slirp_openpty(&fd0[0], &fd0[1]) == -1) {
889
          close(fd[0]);
890
          close(fd[1]);
891
          lprint("Error: openpty failed: %s\n", strerror(errno));
892
          return 0;
893
        }
894
#endif
895
        
896
        switch(fork()) {
897
         case -1:
898
           lprint("Error: fork failed: %s\n", strerror(errno));
899
           close(fd[0]);
900
           close(fd[1]);
901
           close(fd0[0]);
902
           close(fd0[1]);
903
           return 0;
904
           
905
         case 0:
906
           close(fd[0]);
907
           close(fd0[0]);
908
           
909
                /* Set the DISPLAY */
910
           if (x_port >= 0) {
911
#ifdef HAVE_SETENV
912
             sprintf(buff, "%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
913
             setenv("DISPLAY", buff, 1);
914
#else
915
             sprintf(buff, "DISPLAY=%s:%d.%d", inet_ntoa(our_addr), x_port, x_screen);
916
             putenv(buff);
917
#endif
918
           }
919
           
920
           dup2(fd0[1], 0);
921
           dup2(fd0[1], 1);
922
           dup2(fd[1], 2);
923
           for (s = 3; s <= 255; s++)
924
             close(s);
925
           
926
           execlp("rsh","rsh","-l", user, host, args, NULL);
927
           
928
           /* Ooops, failed, let's tell the user why */
929
           
930
           sprintf(buff, "Error: execlp of %s failed: %s\n", 
931
                   "rsh", strerror(errno));
932
           write(2, buff, strlen(buff)+1);
933
           close(0); close(1); close(2); /* XXX */
934
           exit(1);
935
           
936
        default:
937
          close(fd[1]);
938
          close(fd0[1]);
939
          ns->s=fd[0];
940
          so->s=fd0[0];
941
          
942
          return 1;
943
        }
944
}
945
#endif