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