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