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