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