Merge from vendor branch GDB:
[dragonfly.git] / sys / emulation / svr4 / svr4_stream.c
1 /*
2  * Copyright (c) 1998 Mark Newton.  All rights reserved.
3  * Copyright (c) 1994, 1996 Christos Zoulas.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by Christos Zoulas.
16  * 4. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  * 
30  * $FreeBSD: src/sys/svr4/svr4_stream.c,v 1.12.2.2 2000/11/26 04:42:27 dillon Exp $
31  * $DragonFly: src/sys/emulation/svr4/Attic/svr4_stream.c,v 1.14 2005/06/22 01:33:29 dillon Exp $
32  */
33
34 /*
35  * Pretend that we have streams...
36  * Yes, this is gross.
37  *
38  * ToDo: The state machine for getmsg needs re-thinking
39  */
40
41 #define COMPAT_43 1
42
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/buf.h>
46 #include <sys/malloc.h>
47 #include <sys/file.h>
48 #include <sys/filedesc.h>
49 #include <sys/fcntl.h>
50 #include <sys/filio.h>
51 #include <sys/select.h>
52 #include <sys/socket.h>
53 #include <sys/socketvar.h>
54 #include <sys/socketops.h>
55 #include <sys/un.h>
56 #include <netinet/in.h>
57 #include <sys/mbuf.h>
58 #include <sys/protosw.h>
59 #include <sys/signal.h>
60 #include <sys/signalvar.h>
61 #include <sys/uio.h>
62 #include <sys/ktrace.h>
63 #include <sys/proc.h>
64 #include <sys/stat.h>
65 #include <sys/file2.h>
66
67 #include <sys/sysproto.h>
68
69 #include "svr4.h"
70 #include "svr4_types.h"
71 #include "svr4_util.h"
72 #include "svr4_signal.h"
73 #include "svr4_proto.h"
74 #include "svr4_stropts.h"
75 #include "svr4_timod.h"
76 #include "svr4_sockmod.h"
77 #include "svr4_ioctl.h"
78 #include "svr4_socket.h"
79
80 /* Utils */
81 static int clean_pipe (const char *);
82 static void getparm (struct file *, struct svr4_si_sockparms *);
83
84 /* Address Conversions */
85 static void sockaddr_to_netaddr_in (struct svr4_strmcmd *,
86                                         const struct sockaddr_in *);
87 static void sockaddr_to_netaddr_un (struct svr4_strmcmd *,
88                                         const struct sockaddr_un *);
89 static void netaddr_to_sockaddr_in (struct sockaddr_in *,
90                                         const struct svr4_strmcmd *);
91 static void netaddr_to_sockaddr_un (struct sockaddr_un *,
92                                         const struct svr4_strmcmd *);
93
94 /* stream ioctls */
95 static int i_nread (struct file *, struct thread *, register_t *, int,
96                         u_long, caddr_t);
97 static int i_fdinsert (struct file *, struct thread *, register_t *, int,
98                            u_long, caddr_t);
99 static int i_str   (struct file *, struct thread *, register_t *, int,
100                         u_long, caddr_t);
101 static int i_setsig   (struct file *, struct thread *, register_t *, int,
102                         u_long, caddr_t);
103 static int i_getsig   (struct file *, struct thread *, register_t *, int,
104                         u_long, caddr_t);
105 static int _i_bind_rsvd (struct file *, struct thread *, register_t *, int,
106                              u_long, caddr_t);
107 static int _i_rele_rsvd (struct file *, struct thread *, register_t *, int,
108                              u_long, caddr_t);
109
110 /* i_str sockmod calls */
111 static int sockmod       (struct file *, int, struct svr4_strioctl *,
112                               struct thread *);
113 static int si_listen     (struct file *, int, struct svr4_strioctl *,
114                               struct thread *);
115 static int si_ogetudata  (struct file *, int, struct svr4_strioctl *,
116                               struct thread *);
117 static int si_sockparams (struct file *, int, struct svr4_strioctl *,
118                               struct thread *);
119 static int si_shutdown   (struct file *, int, struct svr4_strioctl *,
120                               struct thread *);
121 static int si_getudata   (struct file *, int, struct svr4_strioctl *,
122                               struct thread *);
123
124 /* i_str timod calls */
125 static int timod         (struct file *, int, struct svr4_strioctl *,
126                               struct thread *);
127 static int ti_getinfo    (struct file *, int, struct svr4_strioctl *,
128                               struct thread *);
129 static int ti_bind       (struct file *, int, struct svr4_strioctl *,
130                               struct thread *);
131
132 /* infrastructure */
133 static int svr4_sendit (struct thread *td, int s, struct msghdr *mp,
134                             int flags, int *retval);
135
136 static int svr4_recvit (struct thread *td, int s, struct msghdr *mp,
137                             caddr_t namelenp, int *retval);
138
139 /* <sigh>  Ok, so we shouldn't use sendit() in uipc_syscalls.c because
140  * it isn't part of a "public" interface;  We're supposed to use
141  * pru_sosend instead.  Same goes for recvit()/pru_soreceive() for
142  * that matter.  Solution:  Suck sendit()/recvit() into here where we
143  * can do what we like.
144  * 
145  * I hate code duplication. 
146  * 
147  * I will take out all the #ifdef COMPAT_OLDSOCK gumph, though.
148  */
149 static int
150 svr4_sendit(td, s, mp, flags, retval)
151         struct thread *td;
152         int s;
153         struct msghdr *mp;
154         int flags;
155         int *retval;
156 {
157         struct proc *p;
158         struct file *fp;
159         struct uio auio;
160         struct iovec *iov;
161         int i;
162         struct mbuf *control;
163         struct sockaddr *to;
164         int len, error;
165         struct socket *so;
166 #ifdef KTRACE
167         struct iovec *ktriov = NULL;
168         struct uio ktruio;
169 #endif
170
171         p = td->td_proc;
172         KKASSERT(p);
173
174         error = holdsock(p->p_fd, s, &fp);
175         if (error)
176                 return (error);
177         auio.uio_iov = mp->msg_iov;
178         auio.uio_iovcnt = mp->msg_iovlen;
179         auio.uio_segflg = UIO_USERSPACE;
180         auio.uio_rw = UIO_WRITE;
181         auio.uio_td = td;
182         auio.uio_offset = 0;                    /* XXX */
183         auio.uio_resid = 0;
184         iov = mp->msg_iov;
185         for (i = 0; i < mp->msg_iovlen; i++, iov++) {
186                 if ((auio.uio_resid += iov->iov_len) < 0) {
187                         fdrop(fp, td);
188                         return (EINVAL);
189                 }
190         }
191         if (mp->msg_name) {
192                 error = getsockaddr(&to, mp->msg_name, mp->msg_namelen);
193                 if (error) {
194                         fdrop(fp, td);
195                         return (error);
196                 }
197         } else {
198                 to = 0;
199         }
200         if (mp->msg_control) {
201                 if (mp->msg_controllen < sizeof(struct cmsghdr)) {
202                         error = EINVAL;
203                         goto bad;
204                 }
205                 control = m_get(MB_WAIT, MT_CONTROL);
206                 if (control == NULL) {
207                         error = ENOBUFS;
208                         goto bad;
209                 }
210                 control->m_len = mp->msg_controllen;
211                 error = copyin(mp->msg_control, mtod(control, caddr_t),
212                     mp->msg_controllen);
213                 if (error) {
214                         m_free(control);
215                         goto bad;
216                 }
217         } else {
218                 control = 0;
219         }
220 #ifdef KTRACE
221         if (KTRPOINT(p->p_thread, KTR_GENIO)) {
222                 int iovlen = auio.uio_iovcnt * sizeof (struct iovec);
223
224                 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
225                 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
226                 ktruio = auio;
227         }
228 #endif
229         len = auio.uio_resid;
230         so = (struct socket *)fp->f_data;
231         error = so_pru_sosend(so, to, &auio, NULL, control, flags, td);
232         if (error) {
233                 if (auio.uio_resid != len && (error == ERESTART ||
234                     error == EINTR || error == EWOULDBLOCK))
235                         error = 0;
236                 if (error == EPIPE)
237                         psignal(p, SIGPIPE);
238         }
239         if (error == 0)
240                 *retval = len - auio.uio_resid;
241 #ifdef KTRACE
242         if (ktriov != NULL) {
243                 if (error == 0) {
244                         ktruio.uio_iov = ktriov;
245                         ktruio.uio_resid = *retval;
246                         ktrgenio(p->p_tracep, s, UIO_WRITE, &ktruio, error);
247                 }
248                 FREE(ktriov, M_TEMP);
249         }
250 #endif
251 bad:
252         fdrop(fp, td);
253         if (to)
254                 FREE(to, M_SONAME);
255         return (error);
256 }
257
258 static int
259 svr4_recvit(td, s, mp, namelenp, retval)
260         struct thread *td;
261         int s;
262         struct msghdr *mp;
263         caddr_t namelenp;
264         int *retval;
265 {
266         struct proc *p = td->td_proc;
267         struct file *fp;
268         struct uio auio;
269         struct iovec *iov;
270         int i;
271         int len, error;
272         struct mbuf *m, *control = 0;
273         caddr_t ctlbuf;
274         struct socket *so;
275         struct sockaddr *fromsa = 0;
276 #ifdef KTRACE
277         struct iovec *ktriov = NULL;
278         struct uio ktruio;
279 #endif
280         p = td->td_proc;
281         KKASSERT(p);
282
283         error = holdsock(p->p_fd, s, &fp);
284         if (error)
285                 return (error);
286         auio.uio_iov = mp->msg_iov;
287         auio.uio_iovcnt = mp->msg_iovlen;
288         auio.uio_segflg = UIO_USERSPACE;
289         auio.uio_rw = UIO_READ;
290         auio.uio_td = td;
291         auio.uio_offset = 0;                    /* XXX */
292         auio.uio_resid = 0;
293         iov = mp->msg_iov;
294         for (i = 0; i < mp->msg_iovlen; i++, iov++) {
295                 if ((auio.uio_resid += iov->iov_len) < 0) {
296                         fdrop(fp, td);
297                         return (EINVAL);
298                 }
299         }
300 #ifdef KTRACE
301         if (KTRPOINT(p->p_thread, KTR_GENIO)) {
302                 int iovlen = auio.uio_iovcnt * sizeof (struct iovec);
303
304                 MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK);
305                 bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen);
306                 ktruio = auio;
307         }
308 #endif
309         len = auio.uio_resid;
310         so = (struct socket *)fp->f_data;
311         error = so_pru_soreceive(so, &fromsa, &auio, NULL,
312             mp->msg_control ? &control : NULL, &mp->msg_flags);
313         if (error) {
314                 if (auio.uio_resid != len && (error == ERESTART ||
315                     error == EINTR || error == EWOULDBLOCK))
316                         error = 0;
317         }
318 #ifdef KTRACE
319         if (ktriov != NULL) {
320                 if (error == 0) {
321                         ktruio.uio_iov = ktriov;
322                         ktruio.uio_resid = len - auio.uio_resid;
323                         ktrgenio(p->p_tracep, s, UIO_READ, &ktruio, error);
324                 }
325                 FREE(ktriov, M_TEMP);
326         }
327 #endif
328         if (error)
329                 goto out;
330         *retval = len - auio.uio_resid;
331         if (mp->msg_name) {
332                 len = mp->msg_namelen;
333                 if (len <= 0 || fromsa == 0)
334                         len = 0;
335                 else {
336 #ifndef MIN
337 #define MIN(a,b) ((a)>(b)?(b):(a))
338 #endif
339                         /* save sa_len before it is destroyed by MSG_COMPAT */
340                         len = MIN(len, fromsa->sa_len);
341                         error = copyout(fromsa,
342                             (caddr_t)mp->msg_name, (unsigned)len);
343                         if (error)
344                                 goto out;
345                 }
346                 mp->msg_namelen = len;
347                 if (namelenp &&
348                     (error = copyout((caddr_t)&len, namelenp, sizeof (int)))) {
349                         goto out;
350                 }
351         }
352         if (mp->msg_control) {
353                 len = mp->msg_controllen;
354                 m = control;
355                 mp->msg_controllen = 0;
356                 ctlbuf = (caddr_t) mp->msg_control;
357
358                 while (m && len > 0) {
359                         unsigned int tocopy;
360
361                         if (len >= m->m_len) 
362                                 tocopy = m->m_len;
363                         else {
364                                 mp->msg_flags |= MSG_CTRUNC;
365                                 tocopy = len;
366                         }
367                 
368                         if ((error = copyout((caddr_t)mtod(m, caddr_t),
369                                         ctlbuf, tocopy)) != 0)
370                                 goto out;
371
372                         ctlbuf += tocopy;
373                         len -= tocopy;
374                         m = m->m_next;
375                 }
376                 mp->msg_controllen = ctlbuf - (caddr_t)mp->msg_control;
377         }
378 out:
379         if (fromsa)
380                 FREE(fromsa, M_SONAME);
381         if (control)
382                 m_freem(control);
383         fdrop(fp, td);
384         return (error);
385 }
386
387 #ifdef DEBUG_SVR4
388 static void bufprint (u_char *, size_t);
389 static int show_ioc (const char *, struct svr4_strioctl *);
390 static int show_strbuf (struct svr4_strbuf *);
391 static void show_msg (const char *, int, struct svr4_strbuf *, 
392                           struct svr4_strbuf *, int);
393
394 static void
395 bufprint(buf, len)
396         u_char *buf;
397         size_t len;
398 {
399         size_t i;
400
401         uprintf("\n\t");
402         for (i = 0; i < len; i++) {
403                 uprintf("%x ", buf[i]);
404                 if (i && (i % 16) == 0) 
405                         uprintf("\n\t");
406         }
407 }
408
409 static int
410 show_ioc(str, ioc)
411         const char              *str;
412         struct svr4_strioctl    *ioc;
413 {
414         u_char *ptr = (u_char *) malloc(ioc->len, M_TEMP, M_WAITOK);
415         int error;
416
417         uprintf("%s cmd = %ld, timeout = %d, len = %d, buf = %p { ",
418             str, ioc->cmd, ioc->timeout, ioc->len, ioc->buf);
419
420         if ((error = copyin(ioc->buf, ptr, ioc->len)) != 0) {
421                 free((char *) ptr, M_TEMP);
422                 return error;
423         }
424
425         bufprint(ptr, ioc->len);
426
427         uprintf("}\n");
428
429         free((char *) ptr, M_TEMP);
430         return 0;
431 }
432
433
434 static int
435 show_strbuf(str)
436         struct svr4_strbuf *str;
437 {
438         int error;
439         u_char *ptr = NULL;
440         int maxlen = str->maxlen;
441         int len = str->len;
442
443         if (maxlen < 0)
444                 maxlen = 0;
445
446         if (len >= maxlen)
447                 len = maxlen;
448
449         if (len > 0) {
450             ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK);
451
452             if ((error = copyin(str->buf, ptr, len)) != 0) {
453                     free((char *) ptr, M_TEMP);
454                     return error;
455             }
456         }
457
458         uprintf(", { %d, %d, %p=[ ", str->maxlen, str->len, str->buf);
459
460         if (ptr)
461                 bufprint(ptr, len);
462
463         uprintf("]}");
464
465         if (ptr)
466                 free((char *) ptr, M_TEMP);
467
468         return 0;
469 }
470
471
472 static void
473 show_msg(str, fd, ctl, dat, flags)
474         const char              *str;
475         int                      fd;
476         struct svr4_strbuf      *ctl;
477         struct svr4_strbuf      *dat;
478         int                      flags;
479 {
480         struct svr4_strbuf      buf;
481         int error;
482
483         uprintf("%s(%d", str, fd);
484         if (ctl != NULL) {
485                 if ((error = copyin(ctl, &buf, sizeof(buf))) != 0)
486                         return;
487                 show_strbuf(&buf);
488         }
489         else 
490                 uprintf(", NULL");
491
492         if (dat != NULL) {
493                 if ((error = copyin(dat, &buf, sizeof(buf))) != 0)
494                         return;
495                 show_strbuf(&buf);
496         }
497         else 
498                 uprintf(", NULL");
499
500         uprintf(", %x);\n", flags);
501 }
502
503 #endif /* DEBUG_SVR4 */
504
505 /*
506  * We are faced with an interesting situation. On svr4 unix sockets
507  * are really pipes. But we really have sockets, and we might as
508  * well use them. At the point where svr4 calls TI_BIND, it has
509  * already created a named pipe for the socket using mknod(2).
510  * We need to create a socket with the same name when we bind,
511  * so we need to remove the pipe before, otherwise we'll get address
512  * already in use. So we *carefully* remove the pipe, to avoid
513  * using this as a random file removal tool. We use system calls
514  * to avoid code duplication.
515  */
516 static int
517 clean_pipe(const char *path)
518 {
519         struct lstat_args la;
520         struct unlink_args ua;
521         struct stat st;
522         int error;
523         caddr_t sg = stackgap_init();
524         size_t l = strlen(path) + 1;
525         void *tpath;
526
527         tpath = stackgap_alloc(&sg, l);
528         SCARG(&la, ub) = stackgap_alloc(&sg, sizeof(struct stat));
529
530         if ((error = copyout(path, tpath, l)) != 0)
531                 return error;
532
533         SCARG(&la, path) = tpath;
534
535         if ((error = lstat(&la)) != 0)
536                 return 0;
537
538         if ((error = copyin(SCARG(&la, ub), &st, sizeof(st))) != 0)
539                 return 0;
540
541         /*
542          * Make sure we are dealing with a mode 0 named pipe.
543          */
544         if ((st.st_mode & S_IFMT) != S_IFIFO)
545                 return 0;
546
547         if ((st.st_mode & ALLPERMS) != 0)
548                 return 0;
549
550         SCARG(&ua, path) = SCARG(&la, path);
551
552         if ((error = unlink(&ua)) != 0) {
553                 DPRINTF(("clean_pipe: unlink failed %d\n", error));
554                 return error;
555         }
556
557         return 0;
558 }
559
560
561 static void
562 sockaddr_to_netaddr_in(sc, sain)
563         struct svr4_strmcmd *sc;
564         const struct sockaddr_in *sain;
565 {
566         struct svr4_netaddr_in *na;
567         na = SVR4_ADDROF(sc);
568
569         na->family = sain->sin_family;
570         na->port = sain->sin_port;
571         na->addr = sain->sin_addr.s_addr;
572         DPRINTF(("sockaddr_in -> netaddr %d %d %lx\n", na->family, na->port,
573                  na->addr));
574 }
575
576
577 static void
578 sockaddr_to_netaddr_un(sc, saun)
579         struct svr4_strmcmd *sc;
580         const struct sockaddr_un *saun;
581 {
582         struct svr4_netaddr_un *na;
583         char *dst, *edst = ((char *) sc) + sc->offs + sizeof(na->family) + 1  -
584             sizeof(*sc);
585         const char *src;
586
587         na = SVR4_ADDROF(sc);
588         na->family = saun->sun_family;
589         for (src = saun->sun_path, dst = na->path; (*dst++ = *src++) != '\0'; )
590                 if (dst == edst)
591                         break;
592         DPRINTF(("sockaddr_un -> netaddr %d %s\n", na->family, na->path));
593 }
594
595
596 static void
597 netaddr_to_sockaddr_in(sain, sc)
598         struct sockaddr_in *sain;
599         const struct svr4_strmcmd *sc;
600 {
601         const struct svr4_netaddr_in *na;
602
603
604         na = SVR4_C_ADDROF(sc);
605         memset(sain, 0, sizeof(*sain));
606         sain->sin_len = sizeof(*sain);
607         sain->sin_family = na->family;
608         sain->sin_port = na->port;
609         sain->sin_addr.s_addr = na->addr;
610         DPRINTF(("netaddr -> sockaddr_in %d %d %x\n", sain->sin_family,
611                  sain->sin_port, sain->sin_addr.s_addr));
612 }
613
614
615 static void
616 netaddr_to_sockaddr_un(saun, sc)
617         struct sockaddr_un *saun;
618         const struct svr4_strmcmd *sc;
619 {
620         const struct svr4_netaddr_un *na;
621         char *dst, *edst = &saun->sun_path[sizeof(saun->sun_path) - 1];
622         const char *src;
623
624         na = SVR4_C_ADDROF(sc);
625         memset(saun, 0, sizeof(*saun));
626         saun->sun_family = na->family;
627         for (src = na->path, dst = saun->sun_path; (*dst++ = *src++) != '\0'; )
628                 if (dst == edst)
629                         break;
630         saun->sun_len = dst - saun->sun_path;
631         DPRINTF(("netaddr -> sockaddr_un %d %s\n", saun->sun_family,
632                  saun->sun_path));
633 }
634
635
636 static void
637 getparm(fp, pa)
638         struct file *fp;
639         struct svr4_si_sockparms *pa;
640 {
641         struct svr4_strm *st = svr4_stream_get(fp);
642         struct socket *so = (struct socket *) fp->f_data;
643
644         if (st == NULL)
645                 return;
646
647         pa->family = st->s_family;
648
649         switch (so->so_type) {
650         case SOCK_DGRAM:
651                 pa->type = SVR4_T_CLTS;
652                 pa->protocol = IPPROTO_UDP;
653                 DPRINTF(("getparm(dgram)\n"));
654                 return;
655
656         case SOCK_STREAM:
657                 pa->type = SVR4_T_COTS;  /* What about T_COTS_ORD? XXX */
658                 pa->protocol = IPPROTO_IP;
659                 DPRINTF(("getparm(stream)\n"));
660                 return;
661
662         case SOCK_RAW:
663                 pa->type = SVR4_T_CLTS;
664                 pa->protocol = IPPROTO_RAW;
665                 DPRINTF(("getparm(raw)\n"));
666                 return;
667
668         default:
669                 pa->type = 0;
670                 pa->protocol = 0;
671                 DPRINTF(("getparm(type %d?)\n", so->so_type));
672                 return;
673         }
674 }
675
676
677 static int
678 si_ogetudata(fp, fd, ioc, td)
679         struct file             *fp;
680         int                      fd;
681         struct svr4_strioctl    *ioc;
682         struct thread           *td;
683 {
684         int error;
685         struct svr4_si_oudata ud;
686         struct svr4_si_sockparms pa;
687
688         if (ioc->len != sizeof(ud) && ioc->len != sizeof(ud) - sizeof(int)) {
689                 DPRINTF(("SI_OGETUDATA: Wrong size %d != %d\n",
690                          sizeof(ud), ioc->len));
691                 return EINVAL;
692         }
693
694         if ((error = copyin(ioc->buf, &ud, sizeof(ud))) != 0)
695                 return error;
696
697         getparm(fp, &pa);
698
699         switch (pa.family) {
700         case AF_INET:
701             ud.tidusize = 16384;
702             ud.addrsize = sizeof(struct svr4_sockaddr_in);
703             if (pa.type == SVR4_SOCK_STREAM) 
704                     ud.etsdusize = 1;
705             else
706                     ud.etsdusize = 0;
707             break;
708
709         case AF_LOCAL:
710             ud.tidusize = 65536;
711             ud.addrsize = 128;
712             ud.etsdusize = 128;
713             break;
714
715         default:
716             DPRINTF(("SI_OGETUDATA: Unsupported address family %d\n",
717                      pa.family));
718             return ENOSYS;
719         }
720
721         /* I have no idea what these should be! */
722         ud.optsize = 128;
723         ud.tsdusize = 128;
724
725         ud.servtype = pa.type;
726
727         /* XXX: Fixme */
728         ud.so_state = 0;
729         ud.so_options = 0;
730         return copyout(&ud, ioc->buf, ioc->len);
731 }
732
733
734 static int
735 si_sockparams(fp, fd, ioc, td)
736         struct file             *fp;
737         int                      fd;
738         struct svr4_strioctl    *ioc;
739         struct thread           *td;
740 {
741         struct svr4_si_sockparms pa;
742
743         getparm(fp, &pa);
744         return copyout(&pa, ioc->buf, sizeof(pa));
745 }
746
747
748 static int
749 si_listen(fp, fd, ioc, td)
750         struct file             *fp;
751         int                      fd;
752         struct svr4_strioctl    *ioc;
753         struct thread           *td;
754 {
755         int error;
756         struct svr4_strm *st = svr4_stream_get(fp);
757         struct svr4_strmcmd lst;
758         struct listen_args la;
759
760         if (st == NULL)
761                 return EINVAL;
762
763         if ((error = copyin(ioc->buf, &lst, ioc->len)) != 0)
764                 return error;
765
766         if (lst.cmd != SVR4_TI_OLD_BIND_REQUEST) {
767                 DPRINTF(("si_listen: bad request %ld\n", lst.cmd));
768                 return EINVAL;
769         }
770
771         /*
772          * We are making assumptions again...
773          */
774         SCARG(&la, s) = fd;
775         DPRINTF(("SI_LISTEN: fileno %d backlog = %d\n", fd, 5));
776         SCARG(&la, backlog) = 5;
777
778         if ((error = listen(&la)) != 0) {
779                 DPRINTF(("SI_LISTEN: listen failed %d\n", error));
780                 return error;
781         }
782
783         st->s_cmd = SVR4_TI__ACCEPT_WAIT;
784         lst.cmd = SVR4_TI_BIND_REPLY;
785
786         switch (st->s_family) {
787         case AF_INET:
788                 /* XXX: Fill the length here */
789                 break;
790
791         case AF_LOCAL:
792                 lst.len = 140;
793                 lst.pad[28] = 0x00000000;       /* magic again */
794                 lst.pad[29] = 0x00000800;       /* magic again */
795                 lst.pad[30] = 0x80001400;       /* magic again */
796                 break;
797
798         default:
799                 DPRINTF(("SI_LISTEN: Unsupported address family %d\n",
800                     st->s_family));
801                 return ENOSYS;
802         }
803
804
805         if ((error = copyout(&lst, ioc->buf, ioc->len)) != 0)
806                 return error;
807
808         return 0;
809 }
810
811
812 static int
813 si_getudata(fp, fd, ioc, td)
814         struct file             *fp;
815         int                      fd;
816         struct svr4_strioctl    *ioc;
817         struct thread           *td;
818 {
819         int error;
820         struct svr4_si_udata ud;
821
822         if (sizeof(ud) != ioc->len) {
823                 DPRINTF(("SI_GETUDATA: Wrong size %d != %d\n",
824                          sizeof(ud), ioc->len));
825                 return EINVAL;
826         }
827
828         if ((error = copyin(ioc->buf, &ud, sizeof(ud))) != 0)
829                 return error;
830
831         getparm(fp, &ud.sockparms);
832
833         switch (ud.sockparms.family) {
834         case AF_INET:
835             DPRINTF(("getudata_inet\n"));
836             ud.tidusize = 16384;
837             ud.tsdusize = 16384;
838             ud.addrsize = sizeof(struct svr4_sockaddr_in);
839             if (ud.sockparms.type == SVR4_SOCK_STREAM) 
840                     ud.etsdusize = 1;
841             else
842                     ud.etsdusize = 0;
843             ud.optsize = 0;
844             break;
845
846         case AF_LOCAL:
847             DPRINTF(("getudata_local\n"));
848             ud.tidusize = 65536;
849             ud.tsdusize = 128;
850             ud.addrsize = 128;
851             ud.etsdusize = 128;
852             ud.optsize = 128;
853             break;
854
855         default:
856             DPRINTF(("SI_GETUDATA: Unsupported address family %d\n",
857                      ud.sockparms.family));
858             return ENOSYS;
859         }
860
861
862         ud.servtype = ud.sockparms.type;
863         DPRINTF(("ud.servtype = %d\n", ud.servtype));
864         /* XXX: Fixme */
865         ud.so_state = 0;
866         ud.so_options = 0;
867         return copyout(&ud, ioc->buf, sizeof(ud));
868 }
869
870
871 static int
872 si_shutdown(fp, fd, ioc, td)
873         struct file             *fp;
874         int                      fd;
875         struct svr4_strioctl    *ioc;
876         struct thread           *td;
877 {
878         int error;
879         struct shutdown_args ap;
880
881         if (ioc->len != sizeof(SCARG(&ap, how))) {
882                 DPRINTF(("SI_SHUTDOWN: Wrong size %d != %d\n",
883                          sizeof(SCARG(&ap, how)), ioc->len));
884                 return EINVAL;
885         }
886
887         if ((error = copyin(ioc->buf, &SCARG(&ap, how), ioc->len)) != 0)
888                 return error;
889
890         SCARG(&ap, s) = fd;
891
892         return shutdown(&ap);
893 }
894
895
896 static int
897 sockmod(fp, fd, ioc, td)
898         struct file             *fp;
899         int                      fd;
900         struct svr4_strioctl    *ioc;
901         struct thread           *td;
902 {
903         switch (ioc->cmd) {
904         case SVR4_SI_OGETUDATA:
905                 DPRINTF(("SI_OGETUDATA\n"));
906                 return si_ogetudata(fp, fd, ioc, td);
907
908         case SVR4_SI_SHUTDOWN:
909                 DPRINTF(("SI_SHUTDOWN\n"));
910                 return si_shutdown(fp, fd, ioc, td);
911
912         case SVR4_SI_LISTEN:
913                 DPRINTF(("SI_LISTEN\n"));
914                 return si_listen(fp, fd, ioc, td);
915
916         case SVR4_SI_SETMYNAME:
917                 DPRINTF(("SI_SETMYNAME\n"));
918                 return 0;
919
920         case SVR4_SI_SETPEERNAME:
921                 DPRINTF(("SI_SETPEERNAME\n"));
922                 return 0;
923
924         case SVR4_SI_GETINTRANSIT:
925                 DPRINTF(("SI_GETINTRANSIT\n"));
926                 return 0;
927
928         case SVR4_SI_TCL_LINK:
929                 DPRINTF(("SI_TCL_LINK\n"));
930                 return 0;
931
932         case SVR4_SI_TCL_UNLINK:
933                 DPRINTF(("SI_TCL_UNLINK\n"));
934                 return 0;
935
936         case SVR4_SI_SOCKPARAMS:
937                 DPRINTF(("SI_SOCKPARAMS\n"));
938                 return si_sockparams(fp, fd, ioc, td);
939
940         case SVR4_SI_GETUDATA:
941                 DPRINTF(("SI_GETUDATA\n"));
942                 return si_getudata(fp, fd, ioc, td);
943
944         default:
945                 DPRINTF(("Unknown sockmod ioctl %lx\n", ioc->cmd));
946                 return 0;
947
948         }
949 }
950
951
952 static int
953 ti_getinfo(fp, fd, ioc, td)
954         struct file             *fp;
955         int                      fd;
956         struct svr4_strioctl    *ioc;
957         struct thread           *td;
958 {
959         int error;
960         struct svr4_infocmd info;
961
962         memset(&info, 0, sizeof(info));
963
964         if ((error = copyin(ioc->buf, &info, ioc->len)) != 0)
965                 return error;
966
967         if (info.cmd != SVR4_TI_INFO_REQUEST)
968                 return EINVAL;
969
970         info.cmd = SVR4_TI_INFO_REPLY;
971         info.tsdu = 0;
972         info.etsdu = 1;
973         info.cdata = -2;
974         info.ddata = -2;
975         info.addr = 16;
976         info.opt = -1;
977         info.tidu = 16384;
978         info.serv = 2;
979         info.current = 0;
980         info.provider = 2;
981
982         ioc->len = sizeof(info);
983         if ((error = copyout(&info, ioc->buf, ioc->len)) != 0)
984                 return error;
985
986         return 0;
987 }
988
989
990 static int
991 ti_bind(fp, fd, ioc, td)
992         struct file             *fp;
993         int                      fd;
994         struct svr4_strioctl    *ioc;
995         struct thread           *td;
996 {
997         int error;
998         struct svr4_strm *st = svr4_stream_get(fp);
999         struct sockaddr_in sain;
1000         struct sockaddr_un saun;
1001         caddr_t sg;
1002         void *skp, *sup = NULL;
1003         int sasize;
1004         struct svr4_strmcmd bnd;
1005         struct bind_args ba;
1006
1007         if (st == NULL) {
1008                 DPRINTF(("ti_bind: bad file descriptor\n"));
1009                 return EINVAL;
1010         }
1011
1012         if ((error = copyin(ioc->buf, &bnd, ioc->len)) != 0)
1013                 return error;
1014
1015         if (bnd.cmd != SVR4_TI_OLD_BIND_REQUEST) {
1016                 DPRINTF(("ti_bind: bad request %ld\n", bnd.cmd));
1017                 return EINVAL;
1018         }
1019
1020         switch (st->s_family) {
1021         case AF_INET:
1022                 skp = &sain;
1023                 sasize = sizeof(sain);
1024
1025                 if (bnd.offs == 0)
1026                         goto reply;
1027
1028                 netaddr_to_sockaddr_in(&sain, &bnd);
1029
1030                 DPRINTF(("TI_BIND: fam %d, port %d, addr %x\n",
1031                          sain.sin_family, sain.sin_port,
1032                          sain.sin_addr.s_addr));
1033                 break;
1034
1035         case AF_LOCAL:
1036                 skp = &saun;
1037                 sasize = sizeof(saun);
1038                 if (bnd.offs == 0)
1039                         goto reply;
1040
1041                 netaddr_to_sockaddr_un(&saun, &bnd);
1042
1043                 if (saun.sun_path[0] == '\0')
1044                         goto reply;
1045
1046                 DPRINTF(("TI_BIND: fam %d, path %s\n",
1047                          saun.sun_family, saun.sun_path));
1048
1049                 if ((error = clean_pipe(saun.sun_path)) != 0)
1050                         return error;
1051
1052                 bnd.pad[28] = 0x00001000;       /* magic again */
1053                 break;
1054
1055         default:
1056                 DPRINTF(("TI_BIND: Unsupported address family %d\n",
1057                          st->s_family));
1058                 return ENOSYS;
1059         }
1060
1061         sg = stackgap_init();
1062         sup = stackgap_alloc(&sg, sasize);
1063
1064         if ((error = copyout(skp, sup, sasize)) != 0)
1065                 return error;
1066
1067         SCARG(&ba, s) = fd;
1068         DPRINTF(("TI_BIND: fileno %d\n", fd));
1069         SCARG(&ba, name) = (void *) sup;
1070         SCARG(&ba, namelen) = sasize;
1071
1072         if ((error = bind(&ba)) != 0) {
1073                 DPRINTF(("TI_BIND: bind failed %d\n", error));
1074                 return error;
1075         }
1076
1077 reply:
1078         if (sup == NULL) {
1079                 memset(&bnd, 0, sizeof(bnd));
1080                 bnd.len = sasize + 4;
1081                 bnd.offs = 0x10;        /* XXX */
1082         }
1083
1084         bnd.cmd = SVR4_TI_BIND_REPLY;
1085
1086         if ((error = copyout(&bnd, ioc->buf, ioc->len)) != 0)
1087                 return error;
1088
1089         return 0;
1090 }
1091
1092
1093 static int
1094 timod(fp, fd, ioc, td)
1095         struct file             *fp;
1096         int                      fd;
1097         struct svr4_strioctl    *ioc;
1098         struct thread           *td;
1099 {
1100         switch (ioc->cmd) {
1101         case SVR4_TI_GETINFO:
1102                 DPRINTF(("TI_GETINFO\n"));
1103                 return ti_getinfo(fp, fd, ioc, td);
1104
1105         case SVR4_TI_OPTMGMT:
1106                 DPRINTF(("TI_OPTMGMT\n"));
1107                 return 0;
1108
1109         case SVR4_TI_BIND:
1110                 DPRINTF(("TI_BIND\n"));
1111                 return ti_bind(fp, fd, ioc, td);
1112
1113         case SVR4_TI_UNBIND:
1114                 DPRINTF(("TI_UNBIND\n"));
1115                 return 0;
1116
1117         default:
1118                 DPRINTF(("Unknown timod ioctl %lx\n", ioc->cmd));
1119                 return 0;
1120         }
1121 }
1122
1123
1124 int
1125 svr4_stream_ti_ioctl(fp, td, retval, fd, cmd, dat)
1126         struct file *fp;
1127         struct thread *td;
1128         register_t *retval;
1129         int fd;
1130         u_long cmd;
1131         caddr_t dat;
1132 {
1133         struct svr4_strbuf skb, *sub = (struct svr4_strbuf *) dat;
1134         struct svr4_strm *st = svr4_stream_get(fp);
1135         int error;
1136         void *skp, *sup;
1137         struct sockaddr_in sain;
1138         struct sockaddr_un saun;
1139         struct svr4_strmcmd sc;
1140         int sasize;
1141         caddr_t sg;
1142         int *lenp;
1143
1144         DPRINTF(("svr4_stream_ti_ioctl\n"));
1145
1146         if (st == NULL)
1147                 return EINVAL;
1148
1149         sc.offs = 0x10;
1150         
1151         if ((error = copyin(sub, &skb, sizeof(skb))) != 0) {
1152                 DPRINTF(("ti_ioctl: error copying in strbuf\n"));
1153                 return error;
1154         }
1155
1156         switch (st->s_family) {
1157         case AF_INET:
1158                 skp = &sain;
1159                 sasize = sizeof(sain);
1160                 break;
1161
1162         case AF_LOCAL:
1163                 skp = &saun;
1164                 sasize = sizeof(saun);
1165                 break;
1166
1167         default:
1168                 DPRINTF(("ti_ioctl: Unsupported address family %d\n",
1169                          st->s_family));
1170                 return ENOSYS;
1171         }
1172
1173         sg = stackgap_init();
1174         sup = stackgap_alloc(&sg, sasize);
1175         lenp = stackgap_alloc(&sg, sizeof(*lenp));
1176
1177         if ((error = copyout(&sasize, lenp, sizeof(*lenp))) != 0) {
1178                 DPRINTF(("ti_ioctl: error copying out lenp\n"));
1179                 return error;
1180         }
1181
1182         switch (cmd) {
1183         case SVR4_TI_GETMYNAME:
1184                 DPRINTF(("TI_GETMYNAME\n"));
1185                 {
1186                         struct getsockname_args ap;
1187                         SCARG(&ap, fdes) = fd;
1188                         SCARG(&ap, asa) = sup;
1189                         SCARG(&ap, alen) = lenp;
1190                         if ((error = getsockname(&ap)) != 0) {
1191                                 DPRINTF(("ti_ioctl: getsockname error\n"));
1192                                 return error;
1193                         }
1194                 }
1195                 break;
1196
1197         case SVR4_TI_GETPEERNAME:
1198                 DPRINTF(("TI_GETPEERNAME\n"));
1199                 {
1200                         struct getpeername_args ap;
1201                         SCARG(&ap, fdes) = fd;
1202                         SCARG(&ap, asa) = sup;
1203                         SCARG(&ap, alen) = lenp;
1204                         if ((error = getpeername(&ap)) != 0) {
1205                                 DPRINTF(("ti_ioctl: getpeername error\n"));
1206                                 return error;
1207                         }
1208                 }
1209                 break;
1210
1211         case SVR4_TI_SETMYNAME:
1212                 DPRINTF(("TI_SETMYNAME\n"));
1213                 return 0;
1214
1215         case SVR4_TI_SETPEERNAME:
1216                 DPRINTF(("TI_SETPEERNAME\n"));
1217                 return 0;
1218         default:
1219                 DPRINTF(("ti_ioctl: Unknown ioctl %lx\n", cmd));
1220                 return ENOSYS;
1221         }
1222
1223         if ((error = copyin(sup, skp, sasize)) != 0) {
1224                 DPRINTF(("ti_ioctl: error copying in socket data\n"));
1225                 return error;
1226         }
1227
1228         if ((error = copyin(lenp, &sasize, sizeof(*lenp))) != 0) {
1229                 DPRINTF(("ti_ioctl: error copying in socket size\n"));
1230                 return error;
1231         }
1232
1233         switch (st->s_family) {
1234         case AF_INET:
1235                 sockaddr_to_netaddr_in(&sc, &sain);
1236                 skb.len = sasize;
1237                 break;
1238
1239         case AF_LOCAL:
1240                 sockaddr_to_netaddr_un(&sc, &saun);
1241                 skb.len = sasize + 4;
1242                 break;
1243
1244         default:
1245                 return ENOSYS;
1246         }
1247
1248
1249         if ((error = copyout(SVR4_ADDROF(&sc), skb.buf, sasize)) != 0) {
1250                 DPRINTF(("ti_ioctl: error copying out socket data\n"));
1251                 return error;
1252         }
1253
1254
1255         if ((error = copyout(&skb, sub, sizeof(skb))) != 0) {
1256                 DPRINTF(("ti_ioctl: error copying out strbuf\n"));
1257                 return error;
1258         }
1259
1260         return error;
1261 }
1262
1263
1264
1265
1266 static int
1267 i_nread(fp, td, retval, fd, cmd, dat)
1268         struct file *fp;
1269         struct thread *td;
1270         register_t *retval;
1271         int fd;
1272         u_long cmd;
1273         caddr_t dat;
1274 {
1275         int error;
1276         int nread = 0;  
1277
1278         /*
1279          * We are supposed to return the message length in nread, and the
1280          * number of messages in retval. We don't have the notion of number
1281          * of stream messages, so we just find out if we have any bytes waiting
1282          * for us, and if we do, then we assume that we have at least one
1283          * message waiting for us.
1284          */
1285         if ((error = fo_ioctl(fp, FIONREAD, (caddr_t) &nread, td)) != 0)
1286                 return error;
1287
1288         if (nread != 0)
1289                 *retval = 1;
1290         else
1291                 *retval = 0;
1292
1293         return copyout(&nread, dat, sizeof(nread));
1294 }
1295
1296 static int
1297 i_fdinsert(fp, td, retval, fd, cmd, dat)
1298         struct file *fp;
1299         struct thread *td;
1300         register_t *retval;
1301         int fd;
1302         u_long cmd;
1303         caddr_t dat;
1304 {
1305         /*
1306          * Major hack again here. We assume that we are using this to
1307          * implement accept(2). If that is the case, we have already
1308          * called accept, and we have stored the file descriptor in
1309          * afd. We find the file descriptor that the code wants to use
1310          * in fd insert, and then we dup2() our accepted file descriptor
1311          * to it.
1312          */
1313         int error;
1314         struct svr4_strm *st = svr4_stream_get(fp);
1315         struct svr4_strfdinsert fdi;
1316         struct dup2_args d2p;
1317         struct close_args clp;
1318
1319         if (st == NULL) {
1320                 DPRINTF(("fdinsert: bad file type\n"));
1321                 return EINVAL;
1322         }
1323
1324         if (st->s_afd == -1) {
1325                 DPRINTF(("fdinsert: accept fd not found\n"));
1326                 return ENOENT;
1327         }
1328
1329         if ((error = copyin(dat, &fdi, sizeof(fdi))) != 0) {
1330                 DPRINTF(("fdinsert: copyin failed %d\n", error));
1331                 return error;
1332         }
1333
1334         SCARG(&d2p, from) = st->s_afd;
1335         SCARG(&d2p, to) = fdi.fd;
1336
1337         if ((error = dup2(&d2p)) != 0) {
1338                 DPRINTF(("fdinsert: dup2(%d, %d) failed %d\n", 
1339                     st->s_afd, fdi.fd, error));
1340                 return error;
1341         }
1342
1343         SCARG(&clp, fd) = st->s_afd;
1344
1345         if ((error = close(&clp)) != 0) {
1346                 DPRINTF(("fdinsert: close(%d) failed %d\n", 
1347                     st->s_afd, error));
1348                 return error;
1349         }
1350
1351         st->s_afd = -1;
1352
1353         *retval = 0;
1354         return 0;
1355 }
1356
1357
1358 static int
1359 _i_bind_rsvd(fp, td, retval, fd, cmd, dat)
1360         struct file *fp;
1361         struct thread *td;
1362         register_t *retval;
1363         int fd;
1364         u_long cmd;
1365         caddr_t dat;
1366 {
1367         struct mkfifo_args ap;
1368
1369         /*
1370          * This is a supposed to be a kernel and library only ioctl.
1371          * It gets called before ti_bind, when we have a unix 
1372          * socket, to physically create the socket transport and
1373          * ``reserve'' it. I don't know how this get reserved inside
1374          * the kernel, but we are going to create it nevertheless.
1375          */
1376         SCARG(&ap, path) = dat;
1377         SCARG(&ap, mode) = S_IFIFO;
1378
1379         return mkfifo(&ap);
1380 }
1381
1382 static int
1383 _i_rele_rsvd(fp, td, retval, fd, cmd, dat)
1384         struct file *fp;
1385         struct thread *td;
1386         register_t *retval;
1387         int fd;
1388         u_long cmd;
1389         caddr_t dat;
1390 {
1391         struct unlink_args ap;
1392
1393         /*
1394          * This is a supposed to be a kernel and library only ioctl.
1395          * I guess it is supposed to release the socket.
1396          */
1397         SCARG(&ap, path) = dat;
1398
1399         return unlink(&ap);
1400 }
1401
1402 static int
1403 i_str(fp, td, retval, fd, cmd, dat)
1404         struct file *fp;
1405         struct thread *td;
1406         register_t *retval;
1407         int fd;
1408         u_long cmd;
1409         caddr_t dat;
1410 {
1411         int                      error;
1412         struct svr4_strioctl     ioc;
1413
1414         if ((error = copyin(dat, &ioc, sizeof(ioc))) != 0)
1415                 return error;
1416
1417 #ifdef DEBUG_SVR4
1418         if ((error = show_ioc(">", &ioc)) != 0)
1419                 return error;
1420 #endif /* DEBUG_SVR4 */
1421
1422         switch (ioc.cmd & 0xff00) {
1423         case SVR4_SIMOD:
1424                 if ((error = sockmod(fp, fd, &ioc, td)) != 0)
1425                         return error;
1426                 break;
1427
1428         case SVR4_TIMOD:
1429                 if ((error = timod(fp, fd, &ioc, td)) != 0)
1430                         return error;
1431                 break;
1432
1433         default:
1434                 DPRINTF(("Unimplemented module %c %ld\n",
1435                          (char) (cmd >> 8), cmd & 0xff));
1436                 return 0;
1437         }
1438
1439 #ifdef DEBUG_SVR4
1440         if ((error = show_ioc("<", &ioc)) != 0)
1441                 return error;
1442 #endif /* DEBUG_SVR4 */
1443         return copyout(&ioc, dat, sizeof(ioc));
1444 }
1445
1446 static int
1447 i_setsig(fp, td, retval, fd, cmd, dat)
1448         struct file *fp;
1449         struct thread *td;
1450         register_t *retval;
1451         int fd;
1452         u_long cmd;
1453         caddr_t dat;
1454 {
1455         /* 
1456          * This is the best we can do for now; we cannot generate
1457          * signals only for specific events so the signal mask gets
1458          * ignored; we save it just to pass it to a possible I_GETSIG...
1459          *
1460          * We alse have to fix the O_ASYNC fcntl bit, so the
1461          * process will get SIGPOLLs.
1462          */
1463         struct proc *p = td->td_proc;
1464         struct fcntl_args fa;
1465         int error;
1466         register_t oflags, flags;
1467         struct svr4_strm *st = svr4_stream_get(fp);
1468
1469         KKASSERT(p);
1470
1471         if (st == NULL) {
1472                 DPRINTF(("i_setsig: bad file descriptor\n"));
1473                 return EINVAL;
1474         }
1475         /* get old status flags */
1476         SCARG(&fa, fd) = fd;
1477         SCARG(&fa, cmd) = F_GETFL;
1478         if ((error = fcntl(&fa)) != 0)
1479                 return error;
1480
1481         oflags = fa.sysmsg_result;
1482
1483         /* update the flags */
1484         if (dat != NULL) {
1485                 int mask;
1486
1487                 flags = oflags | O_ASYNC;
1488                 if ((error = copyin(dat, &mask, sizeof(mask))) != 0) {
1489                           DPRINTF(("i_setsig: bad eventmask pointer\n"));
1490                           return error;
1491                 }
1492                 if (mask & SVR4_S_ALLMASK) {
1493                           DPRINTF(("i_setsig: bad eventmask data %x\n", mask));
1494                           return EINVAL;
1495                 }
1496                 st->s_eventmask = mask;
1497         }
1498         else {
1499                 flags = oflags & ~O_ASYNC;
1500                 st->s_eventmask = 0;
1501         }
1502
1503         /* set the new flags, if changed */
1504         if (flags != oflags) {
1505                 SCARG(&fa, cmd) = F_SETFL;
1506                 SCARG(&fa, arg) = (long) flags;
1507                 if ((error = fcntl(&fa)) != 0)
1508                           return error;
1509                 flags =fa.sysmsg_result;
1510         }
1511
1512         /* set up SIGIO receiver if needed */
1513         if (dat != NULL) {
1514                 SCARG(&fa, cmd) = F_SETOWN;
1515                 SCARG(&fa, arg) = (long) p->p_pid;
1516                 error = fcntl(&fa);
1517                 *retval = fa.sysmsg_result;
1518                 return(error);
1519         }
1520         *retval = fa.sysmsg_result;
1521         return 0;
1522 }
1523
1524 static int
1525 i_getsig(fp, td, retval, fd, cmd, dat)
1526         struct file *fp;
1527         struct thread *td;
1528         register_t *retval;
1529         int fd;
1530         u_long cmd;
1531         caddr_t dat;
1532 {
1533         int error;
1534
1535         if (dat != NULL) {
1536                 struct svr4_strm *st = svr4_stream_get(fp);
1537
1538                 if (st == NULL) {
1539                         DPRINTF(("i_getsig: bad file descriptor\n"));
1540                         return EINVAL;
1541                 }
1542                 if ((error = copyout(&st->s_eventmask, dat, 
1543                                      sizeof(st->s_eventmask))) != 0) {
1544                         DPRINTF(("i_getsig: bad eventmask pointer\n"));
1545                         return error;
1546                 }
1547         }
1548         return 0;
1549 }
1550
1551 int
1552 svr4_stream_ioctl(fp, td, retval, fd, cmd, dat)
1553         struct file *fp;
1554         struct thread *td;
1555         register_t *retval;
1556         int fd;
1557         u_long cmd;
1558         caddr_t dat;
1559 {
1560         *retval = 0;
1561
1562         /*
1563          * All the following stuff assumes "sockmod" is pushed...
1564          */
1565         switch (cmd) {
1566         case SVR4_I_NREAD:
1567                 DPRINTF(("I_NREAD\n"));
1568                 return i_nread(fp, td, retval, fd, cmd, dat);
1569
1570         case SVR4_I_PUSH:
1571                 DPRINTF(("I_PUSH %p\n", dat));
1572 #if defined(DEBUG_SVR4)
1573                 show_strbuf((void *)dat);
1574 #endif
1575                 return 0;
1576
1577         case SVR4_I_POP:
1578                 DPRINTF(("I_POP\n"));
1579                 return 0;
1580
1581         case SVR4_I_LOOK:
1582                 DPRINTF(("I_LOOK\n"));
1583                 return 0;
1584
1585         case SVR4_I_FLUSH:
1586                 DPRINTF(("I_FLUSH\n"));
1587                 return 0;
1588
1589         case SVR4_I_SRDOPT:
1590                 DPRINTF(("I_SRDOPT\n"));
1591                 return 0;
1592
1593         case SVR4_I_GRDOPT:
1594                 DPRINTF(("I_GRDOPT\n"));
1595                 return 0;
1596
1597         case SVR4_I_STR:
1598                 DPRINTF(("I_STR\n"));
1599                 return i_str(fp, td, retval, fd, cmd, dat);
1600
1601         case SVR4_I_SETSIG:
1602                 DPRINTF(("I_SETSIG\n"));
1603                 return i_setsig(fp, td, retval, fd, cmd, dat);
1604
1605         case SVR4_I_GETSIG:
1606                 DPRINTF(("I_GETSIG\n"));
1607                 return i_getsig(fp, td, retval, fd, cmd, dat);
1608
1609         case SVR4_I_FIND:
1610                 DPRINTF(("I_FIND\n"));
1611                 /*
1612                  * Here we are not pushing modules really, we just
1613                  * pretend all are present
1614                  */
1615                 *retval = 0;
1616                 return 0;
1617
1618         case SVR4_I_LINK:
1619                 DPRINTF(("I_LINK\n"));
1620                 return 0;
1621
1622         case SVR4_I_UNLINK:
1623                 DPRINTF(("I_UNLINK\n"));
1624                 return 0;
1625
1626         case SVR4_I_ERECVFD:
1627                 DPRINTF(("I_ERECVFD\n"));
1628                 return 0;
1629
1630         case SVR4_I_PEEK:
1631                 DPRINTF(("I_PEEK\n"));
1632                 return 0;
1633
1634         case SVR4_I_FDINSERT:
1635                 DPRINTF(("I_FDINSERT\n"));
1636                 return i_fdinsert(fp, td, retval, fd, cmd, dat);
1637
1638         case SVR4_I_SENDFD:
1639                 DPRINTF(("I_SENDFD\n"));
1640                 return 0;
1641
1642         case SVR4_I_RECVFD:
1643                 DPRINTF(("I_RECVFD\n"));
1644                 return 0;
1645
1646         case SVR4_I_SWROPT:
1647                 DPRINTF(("I_SWROPT\n"));
1648                 return 0;
1649
1650         case SVR4_I_GWROPT:
1651                 DPRINTF(("I_GWROPT\n"));
1652                 return 0;
1653
1654         case SVR4_I_LIST:
1655                 DPRINTF(("I_LIST\n"));
1656                 return 0;
1657
1658         case SVR4_I_PLINK:
1659                 DPRINTF(("I_PLINK\n"));
1660                 return 0;
1661
1662         case SVR4_I_PUNLINK:
1663                 DPRINTF(("I_PUNLINK\n"));
1664                 return 0;
1665
1666         case SVR4_I_SETEV:
1667                 DPRINTF(("I_SETEV\n"));
1668                 return 0;
1669
1670         case SVR4_I_GETEV:
1671                 DPRINTF(("I_GETEV\n"));
1672                 return 0;
1673
1674         case SVR4_I_STREV:
1675                 DPRINTF(("I_STREV\n"));
1676                 return 0;
1677
1678         case SVR4_I_UNSTREV:
1679                 DPRINTF(("I_UNSTREV\n"));
1680                 return 0;
1681
1682         case SVR4_I_FLUSHBAND:
1683                 DPRINTF(("I_FLUSHBAND\n"));
1684                 return 0;
1685
1686         case SVR4_I_CKBAND:
1687                 DPRINTF(("I_CKBAND\n"));
1688                 return 0;
1689
1690         case SVR4_I_GETBAND:
1691                 DPRINTF(("I_GETBANK\n"));
1692                 return 0;
1693
1694         case SVR4_I_ATMARK:
1695                 DPRINTF(("I_ATMARK\n"));
1696                 return 0;
1697
1698         case SVR4_I_SETCLTIME:
1699                 DPRINTF(("I_SETCLTIME\n"));
1700                 return 0;
1701
1702         case SVR4_I_GETCLTIME:
1703                 DPRINTF(("I_GETCLTIME\n"));
1704                 return 0;
1705
1706         case SVR4_I_CANPUT:
1707                 DPRINTF(("I_CANPUT\n"));
1708                 return 0;
1709
1710         case SVR4__I_BIND_RSVD:
1711                 DPRINTF(("_I_BIND_RSVD\n"));
1712                 return _i_bind_rsvd(fp, td, retval, fd, cmd, dat);
1713
1714         case SVR4__I_RELE_RSVD:
1715                 DPRINTF(("_I_RELE_RSVD\n"));
1716                 return _i_rele_rsvd(fp, td, retval, fd, cmd, dat);
1717
1718         default:
1719                 DPRINTF(("unimpl cmd = %lx\n", cmd));
1720                 break;
1721         }
1722
1723         return 0;
1724 }
1725
1726
1727
1728 int
1729 svr4_sys_putmsg(struct svr4_sys_putmsg_args *uap)
1730 {
1731         struct thread *td = curthread;
1732         struct proc *p = td->td_proc;
1733         struct filedesc *fdp;
1734         struct file     *fp;
1735         struct svr4_strbuf dat, ctl;
1736         struct svr4_strmcmd sc;
1737         struct sockaddr_in sain;
1738         struct sockaddr_un saun;
1739         void *skp, *sup;
1740         int sasize, *retval;
1741         struct svr4_strm *st;
1742         int error;
1743         caddr_t sg;
1744
1745         KKASSERT(p);
1746         fdp = p->p_fd;
1747         retval = &uap->sysmsg_result;
1748         fp = fdp->fd_files[SCARG(uap, fd)].fp;
1749
1750         if (((u_int)SCARG(uap, fd) >= fdp->fd_nfiles) || (fp == NULL)) {
1751 #ifdef DEBUG_SVR4
1752                 uprintf("putmsg: bad fp\n");
1753 #endif
1754                 return EBADF;
1755         }
1756
1757 #ifdef DEBUG_SVR4
1758         show_msg(">putmsg", SCARG(uap, fd), SCARG(uap, ctl),
1759                  SCARG(uap, dat), SCARG(uap, flags));
1760 #endif /* DEBUG_SVR4 */
1761
1762         if (((u_int)SCARG(uap, fd) >= fdp->fd_nfiles) || (fp == NULL)) {
1763 #ifdef DEBUG_SVR4
1764                 uprintf("putmsg: bad fp(2)\n");
1765 #endif
1766                 return EBADF;
1767         }
1768
1769         if (SCARG(uap, ctl) != NULL) {
1770           if ((error = copyin(SCARG(uap, ctl), &ctl, sizeof(ctl))) != 0) {
1771 #ifdef DEBUG_SVR4
1772             uprintf("putmsg: copyin(): %d\n", error);
1773 #endif
1774             return error;
1775           }
1776         }
1777         else
1778                 ctl.len = -1;
1779
1780         if (SCARG(uap, dat) != NULL) {
1781           if ((error = copyin(SCARG(uap, dat), &dat, sizeof(dat))) != 0) {
1782 #ifdef DEBUG_SVR4
1783             uprintf("putmsg: copyin(): %d (2)\n", error);
1784 #endif
1785             return error;
1786           }
1787         }
1788         else
1789                 dat.len = -1;
1790
1791         /*
1792          * Only for sockets for now.
1793          */
1794         if ((st = svr4_stream_get(fp)) == NULL) {
1795                 DPRINTF(("putmsg: bad file type\n"));
1796                 return EINVAL;
1797         }
1798
1799         if (ctl.len > sizeof(sc)) {
1800                 DPRINTF(("putmsg: Bad control size %d != %d\n", ctl.len,
1801                          sizeof(struct svr4_strmcmd)));
1802                 return EINVAL;
1803         }
1804
1805         if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0)
1806                 return error;
1807
1808         switch (st->s_family) {
1809         case AF_INET:
1810                 if (sc.len != sizeof(sain)) {
1811                         if (sc.cmd == SVR4_TI_DATA_REQUEST) {
1812                                 struct write_args wa;
1813
1814                                 /* Solaris seems to use sc.cmd = 3 to
1815                                  * send "expedited" data.  telnet uses
1816                                  * this for options processing, sending EOF,
1817                                  * etc.  I'm sure other things use it too.
1818                                  * I don't have any documentation
1819                                  * on it, so I'm making a guess that this
1820                                  * is how it works. newton@atdot.dotat.org XXX
1821                                  */
1822                                 DPRINTF(("sending expedited data ??\n"));
1823                                 SCARG(&wa, fd) = SCARG(uap, fd);
1824                                 SCARG(&wa, buf) = dat.buf;
1825                                 SCARG(&wa, nbyte) = dat.len;
1826                                 wa.sysmsg_result = 0;
1827
1828                                 error = write(&wa);
1829                                 *retval = wa.sysmsg_result;
1830                                 return(error);
1831                         }
1832                         DPRINTF(("putmsg: Invalid inet length %ld\n", sc.len));
1833                         return EINVAL;
1834                 }
1835                 netaddr_to_sockaddr_in(&sain, &sc);
1836                 skp = &sain;
1837                 sasize = sizeof(sain);
1838                 error = sain.sin_family != st->s_family;
1839                 break;
1840
1841         case AF_LOCAL:
1842                 if (ctl.len == 8) {
1843                         /* We are doing an accept; succeed */
1844                         DPRINTF(("putmsg: Do nothing\n"));
1845                         *retval = 0;
1846                         return 0;
1847                 }
1848                 else {
1849                         /* Maybe we've been given a device/inode pair */
1850                         udev_t *dev = SVR4_ADDROF(&sc);
1851                         ino_t *ino = (ino_t *) &dev[1];
1852                         skp = svr4_find_socket(td, fp, *dev, *ino);
1853                         if (skp == NULL) {
1854                                 skp = &saun;
1855                                 /* I guess we have it by name */
1856                                 netaddr_to_sockaddr_un(skp, &sc);
1857                         }
1858                         sasize = sizeof(saun);
1859                 }
1860                 break;
1861
1862         default:
1863                 DPRINTF(("putmsg: Unsupported address family %d\n",
1864                          st->s_family));
1865                 return ENOSYS;
1866         }
1867
1868         sg = stackgap_init();
1869         sup = stackgap_alloc(&sg, sasize);
1870
1871         if ((error = copyout(skp, sup, sasize)) != 0)
1872                 return error;
1873
1874         switch (st->s_cmd = sc.cmd) {
1875         case SVR4_TI_CONNECT_REQUEST:   /* connect      */
1876                 {
1877                         struct connect_args co;
1878
1879                         SCARG(&co, s) = SCARG(uap, fd);
1880                         SCARG(&co, name) = (void *) sup;
1881                         SCARG(&co, namelen) = (int) sasize;
1882                         co.sysmsg_result = 0;
1883                         
1884                         error = connect(&co);
1885                         *retval = co.sysmsg_result;
1886                         return(error);
1887                 }
1888
1889         case SVR4_TI_SENDTO_REQUEST:    /* sendto       */
1890                 {
1891                         struct msghdr msg;
1892                         struct iovec aiov;
1893
1894                         msg.msg_name = (caddr_t) sup;
1895                         msg.msg_namelen = sasize;
1896                         msg.msg_iov = &aiov;
1897                         msg.msg_iovlen = 1;
1898                         msg.msg_control = 0;
1899                         msg.msg_flags = 0;
1900                         aiov.iov_base = dat.buf;
1901                         aiov.iov_len = dat.len;
1902 #if 0
1903                         error = so_pru_sosend(so, NULL, uio, NULL, NULL, 0,
1904                             uio->uio_td);
1905 #endif
1906                         error = svr4_sendit(td, SCARG(uap, fd), &msg,
1907                                        SCARG(uap, flags), retval);
1908                         DPRINTF(("sendto_request error: %d\n", error));
1909                         *retval = 0;
1910                         return error;
1911                 }
1912
1913         default:
1914                 DPRINTF(("putmsg: Unimplemented command %lx\n", sc.cmd));
1915                 return ENOSYS;
1916         }
1917 }
1918
1919 int
1920 svr4_sys_getmsg(struct svr4_sys_getmsg_args *uap)
1921 {
1922         struct thread *td = curthread;
1923         struct proc *p = td->td_proc;
1924         struct filedesc *fdp;
1925         struct file     *fp;
1926         struct getpeername_args ga;
1927         struct accept_args aa;
1928         struct svr4_strbuf dat, ctl;
1929         struct svr4_strmcmd sc;
1930         int error, *retval;
1931         struct msghdr msg;
1932         struct iovec aiov;
1933         struct sockaddr_in sain;
1934         struct sockaddr_un saun;
1935         void *skp, *sup;
1936         int sasize;
1937         struct svr4_strm *st;
1938         int *flen;
1939         int fl;
1940         caddr_t sg;
1941
1942         KKASSERT(p);
1943         fdp = p->p_fd;
1944         retval = &uap->sysmsg_result;
1945         fp = fdp->fd_files[SCARG(uap, fd)].fp;
1946
1947         if (((u_int)SCARG(uap, fd) >= fdp->fd_nfiles) || (fp == NULL))
1948                 return EBADF;
1949
1950         memset(&sc, 0, sizeof(sc));
1951
1952 #ifdef DEBUG_SVR4
1953         show_msg(">getmsg", SCARG(uap, fd), SCARG(uap, ctl),
1954                  SCARG(uap, dat), 0);
1955 #endif /* DEBUG_SVR4 */
1956                         
1957         if (((u_int)SCARG(uap, fd) >= fdp->fd_nfiles) || (fp == NULL))
1958                 return EBADF;
1959
1960         if (SCARG(uap, ctl) != NULL) {
1961                 if ((error = copyin(SCARG(uap, ctl), &ctl, sizeof(ctl))) != 0)
1962                         return error;
1963         }
1964         else {
1965                 ctl.len = -1;
1966                 ctl.maxlen = 0;
1967         }
1968
1969         if (SCARG(uap, dat) != NULL) {
1970                 if ((error = copyin(SCARG(uap, dat), &dat, sizeof(dat))) != 0)
1971                         return error;
1972         }
1973         else {
1974                 dat.len = -1;
1975                 dat.maxlen = 0;
1976         }
1977
1978         /*
1979          * Only for sockets for now.
1980          */
1981         if ((st = svr4_stream_get(fp)) == NULL) {
1982                 DPRINTF(("getmsg: bad file type\n"));
1983                 return EINVAL;
1984         }
1985
1986         if (ctl.maxlen == -1 || dat.maxlen == -1) {
1987                 DPRINTF(("getmsg: Cannot handle -1 maxlen (yet)\n"));
1988                 return ENOSYS;
1989         }
1990
1991         switch (st->s_family) {
1992         case AF_INET:
1993                 skp = &sain;
1994                 sasize = sizeof(sain);
1995                 break;
1996
1997         case AF_LOCAL:
1998                 skp = &saun;
1999                 sasize = sizeof(saun);
2000                 break;
2001
2002         default:
2003                 DPRINTF(("getmsg: Unsupported address family %d\n",
2004                          st->s_family));
2005                 return ENOSYS;
2006         }
2007
2008         sg = stackgap_init();
2009         sup = stackgap_alloc(&sg, sasize);
2010         flen = (int *) stackgap_alloc(&sg, sizeof(*flen));
2011
2012         fl = sasize;
2013         if ((error = copyout(&fl, flen, sizeof(fl))) != 0)
2014                 return error;
2015
2016         switch (st->s_cmd) {
2017         case SVR4_TI_CONNECT_REQUEST:
2018                 DPRINTF(("getmsg: TI_CONNECT_REQUEST\n"));
2019                 /*
2020                  * We do the connect in one step, so the putmsg should
2021                  * have gotten the error.
2022                  */
2023                 sc.cmd = SVR4_TI_OK_REPLY;
2024                 sc.len = 0;
2025
2026                 ctl.len = 8;
2027                 dat.len = -1;
2028                 fl = 1;
2029                 st->s_cmd = sc.cmd;
2030                 break;
2031
2032         case SVR4_TI_OK_REPLY:
2033                 DPRINTF(("getmsg: TI_OK_REPLY\n"));
2034                 /*
2035                  * We are immediately after a connect reply, so we send
2036                  * a connect verification.
2037                  */
2038
2039                 SCARG(&ga, fdes) = SCARG(uap, fd);
2040                 SCARG(&ga, asa) = (void *) sup;
2041                 SCARG(&ga, alen) = flen;
2042                 
2043                 if ((error = getpeername(&ga)) != 0) {
2044                         DPRINTF(("getmsg: getpeername failed %d\n", error));
2045                         return error;
2046                 }
2047
2048                 if ((error = copyin(sup, skp, sasize)) != 0)
2049                         return error;
2050                 
2051                 sc.cmd = SVR4_TI_CONNECT_REPLY;
2052                 sc.pad[0] = 0x4;
2053                 sc.offs = 0x18;
2054                 sc.pad[1] = 0x14;
2055                 sc.pad[2] = 0x04000402;
2056
2057                 switch (st->s_family) {
2058                 case AF_INET:
2059                         sc.len = sasize;
2060                         sockaddr_to_netaddr_in(&sc, &sain);
2061                         break;
2062
2063                 case AF_LOCAL:
2064                         sc.len = sasize + 4;
2065                         sockaddr_to_netaddr_un(&sc, &saun);
2066                         break;
2067
2068                 default:
2069                         return ENOSYS;
2070                 }
2071
2072                 ctl.len = 40;
2073                 dat.len = -1;
2074                 fl = 0;
2075                 st->s_cmd = sc.cmd;
2076                 break;
2077
2078         case SVR4_TI__ACCEPT_OK:
2079                 DPRINTF(("getmsg: TI__ACCEPT_OK\n"));
2080                 /*
2081                  * We do the connect in one step, so the putmsg should
2082                  * have gotten the error.
2083                  */
2084                 sc.cmd = SVR4_TI_OK_REPLY;
2085                 sc.len = 1;
2086
2087                 ctl.len = 8;
2088                 dat.len = -1;
2089                 fl = 1;
2090                 st->s_cmd = SVR4_TI__ACCEPT_WAIT;
2091                 break;
2092
2093         case SVR4_TI__ACCEPT_WAIT:
2094                 DPRINTF(("getmsg: TI__ACCEPT_WAIT\n"));
2095                 /*
2096                  * We are after a listen, so we try to accept...
2097                  */
2098                 SCARG(&aa, s) = SCARG(uap, fd);
2099                 SCARG(&aa, name) = (void *) sup;
2100                 SCARG(&aa, anamelen) = flen;
2101                 
2102                 if ((error = accept(&aa)) != 0) {
2103                         DPRINTF(("getmsg: accept failed %d\n", error));
2104                         return error;
2105                 }
2106
2107                 st->s_afd = *retval;
2108
2109                 DPRINTF(("getmsg: Accept fd = %d\n", st->s_afd));
2110
2111                 if ((error = copyin(sup, skp, sasize)) != 0)
2112                         return error;
2113                 
2114                 sc.cmd = SVR4_TI_ACCEPT_REPLY;
2115                 sc.offs = 0x18;
2116                 sc.pad[0] = 0x0;
2117
2118                 switch (st->s_family) {
2119                 case AF_INET:
2120                         sc.pad[1] = 0x28;
2121                         sockaddr_to_netaddr_in(&sc, &sain);
2122                         ctl.len = 40;
2123                         sc.len = sasize;
2124                         break;
2125
2126                 case AF_LOCAL:
2127                         sc.pad[1] = 0x00010000;
2128                         sc.pad[2] = 0xf6bcdaa0; /* I don't know what that is */
2129                         sc.pad[3] = 0x00010000;
2130                         ctl.len = 134;
2131                         sc.len = sasize + 4;
2132                         break;
2133
2134                 default:
2135                         return ENOSYS;
2136                 }
2137
2138                 dat.len = -1;
2139                 fl = 0;
2140                 st->s_cmd = SVR4_TI__ACCEPT_OK;
2141                 break;
2142
2143         case SVR4_TI_SENDTO_REQUEST:
2144                 DPRINTF(("getmsg: TI_SENDTO_REQUEST\n"));
2145                 if (ctl.maxlen > 36 && ctl.len < 36)
2146                     ctl.len = 36;
2147
2148                 if ((error = copyin(ctl.buf, &sc, ctl.len)) != 0)
2149                         return error;
2150
2151                 switch (st->s_family) {
2152                 case AF_INET:
2153                         sockaddr_to_netaddr_in(&sc, &sain);
2154                         break;
2155
2156                 case AF_LOCAL:
2157                         sockaddr_to_netaddr_un(&sc, &saun);
2158                         break;
2159
2160                 default:
2161                         return ENOSYS;
2162                 }
2163
2164                 msg.msg_name = (caddr_t) sup;
2165                 msg.msg_namelen = sasize;
2166                 msg.msg_iov = &aiov;
2167                 msg.msg_iovlen = 1;
2168                 msg.msg_control = 0;
2169                 aiov.iov_base = dat.buf;
2170                 aiov.iov_len = dat.maxlen;
2171                 msg.msg_flags = 0;
2172
2173                 error = svr4_recvit(td, SCARG(uap, fd), &msg, (caddr_t) flen, retval);
2174
2175                 if (error) {
2176                         DPRINTF(("getmsg: recvit failed %d\n", error));
2177                         return error;
2178                 }
2179
2180                 if ((error = copyin(msg.msg_name, skp, sasize)) != 0)
2181                         return error;
2182
2183                 sc.cmd = SVR4_TI_RECVFROM_IND;
2184
2185                 switch (st->s_family) {
2186                 case AF_INET:
2187                         sc.len = sasize;
2188                         sockaddr_to_netaddr_in(&sc, &sain);
2189                         break;
2190
2191                 case AF_LOCAL:
2192                         sc.len = sasize + 4;
2193                         sockaddr_to_netaddr_un(&sc, &saun);
2194                         break;
2195
2196                 default:
2197                         return ENOSYS;
2198                 }
2199
2200                 dat.len = *retval;
2201                 fl = 0;
2202                 st->s_cmd = sc.cmd;
2203                 break;
2204
2205         default:
2206                 st->s_cmd = sc.cmd;
2207                 if (st->s_cmd == SVR4_TI_CONNECT_REQUEST) {
2208                         struct read_args ra;
2209
2210                         /* More weirdness:  Again, I can't find documentation
2211                          * to back this up, but when a process does a generic
2212                          * "getmsg()" call it seems that the command field is
2213                          * zero and the length of the data area is zero.  I
2214                          * think processes expect getmsg() to fill in dat.len
2215                          * after reading at most dat.maxlen octets from the
2216                          * stream.  Since we're using sockets I can let 
2217                          * read() look after it and frob return values
2218                          * appropriately (or inappropriately :-)
2219                          *   -- newton@atdot.dotat.org        XXX
2220                          */
2221                         SCARG(&ra, fd) = SCARG(uap, fd);
2222                         SCARG(&ra, buf) = dat.buf;
2223                         SCARG(&ra, nbyte) = dat.maxlen;
2224                         if ((error = read(&ra)) != 0) {
2225                                 return error;
2226                         }
2227                         dat.len = *retval;
2228                         *retval = 0;
2229                         st->s_cmd = SVR4_TI_SENDTO_REQUEST;
2230                         break;
2231                 }
2232                 DPRINTF(("getmsg: Unknown state %x\n", st->s_cmd));
2233                 return EINVAL;
2234         }
2235
2236         if (SCARG(uap, ctl)) {
2237                 if (ctl.len != -1)
2238                         if ((error = copyout(&sc, ctl.buf, ctl.len)) != 0)
2239                                 return error;
2240
2241                 if ((error = copyout(&ctl, SCARG(uap, ctl), sizeof(ctl))) != 0)
2242                         return error;
2243         }
2244
2245         if (SCARG(uap, dat)) {
2246                 if ((error = copyout(&dat, SCARG(uap, dat), sizeof(dat))) != 0)
2247                         return error;
2248         }
2249
2250         if (SCARG(uap, flags)) { /* XXX: Need translation */
2251                 if ((error = copyout(&fl, SCARG(uap, flags), sizeof(fl))) != 0)
2252                         return error;
2253         }
2254
2255         *retval = 0;
2256
2257 #ifdef DEBUG_SVR4
2258         show_msg("<getmsg", SCARG(uap, fd), SCARG(uap, ctl),
2259                  SCARG(uap, dat), fl);
2260 #endif /* DEBUG_SVR4 */
2261         return error;
2262 }
2263
2264 int svr4_sys_send(struct svr4_sys_send_args *uap)
2265 {
2266         struct osend_args osa;
2267         int error;
2268
2269         SCARG(&osa, s) = SCARG(uap, s);
2270         SCARG(&osa, buf) = SCARG(uap, buf);
2271         SCARG(&osa, len) = SCARG(uap, len);
2272         SCARG(&osa, flags) = SCARG(uap, flags);
2273         osa.sysmsg_result = 0;
2274         error = osend(&osa);
2275         uap->sysmsg_result = osa.sysmsg_result;
2276         return(error);
2277 }
2278
2279 int svr4_sys_recv(struct svr4_sys_recv_args *uap)
2280 {
2281         struct orecv_args ora;
2282         int error;
2283
2284         SCARG(&ora, s) = SCARG(uap, s);
2285         SCARG(&ora, buf) = SCARG(uap, buf);
2286         SCARG(&ora, len) = SCARG(uap, len);
2287         SCARG(&ora, flags) = SCARG(uap, flags);
2288         ora.sysmsg_result = 0;
2289         error = orecv(&ora);
2290         uap->sysmsg_result = ora.sysmsg_result;
2291         return(error);
2292 }
2293
2294 /* 
2295  * XXX This isn't necessary, but it's handy for inserting debug code into
2296  * sendto().  Let's leave it here for now...
2297  */     
2298 int
2299 svr4_sys_sendto(struct svr4_sys_sendto_args *uap)
2300 {
2301         struct sendto_args sa;
2302         int error;
2303
2304         SCARG(&sa, s) = SCARG(uap, s);
2305         SCARG(&sa, buf) = SCARG(uap, buf);
2306         SCARG(&sa, len) = SCARG(uap, len);
2307         SCARG(&sa, flags) = SCARG(uap, flags);
2308         SCARG(&sa, to) = (caddr_t)SCARG(uap, to);
2309         SCARG(&sa, tolen) = SCARG(uap, tolen);
2310
2311         DPRINTF(("calling sendto()\n"));
2312         sa.sysmsg_result = 0;
2313         error = sendto(&sa);
2314         uap->sysmsg_result = sa.sysmsg_result;
2315         return(error);
2316 }
2317