The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/compat/svr4/svr4_stream.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 3084df1a027718d8b9d09a84006f4f9b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.