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