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