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