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