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