~ubuntu-branches/ubuntu/feisty/basilisk2/feisty

« back to all changes in this revision

Viewing changes to src/slirp/misc.c

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2005-07-30 20:42:20 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050730204220-1nl1cg2jkjvy63ry
Tags: 0.9.20050730-1
* New upstream CVS snapshot.
* Build-depend on virtual libsdl-dev (not libsdl1.2-dev).
* Invoke init rules also on clean (to separate better from official
  builds).
* Update URL of upstream source in debian/copyright.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
        socklen_t 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