ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/slirp/misc.c
Revision: 1.6
Committed: 2007-01-22T14:48:40Z (17 years, 10 months ago) by asvitkine
Content type: text/plain
Branch: MAIN
Changes since 1.5: +1 -0 lines
Log Message:
fix compile warnings w/ slirp caused by not including stdlib

File Contents

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