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