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

Cache object: 6aa588e9f6131d9f76636172cc317fc4


[ 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.