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_32/svr4_32_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 /*      $NetBSD: svr4_32_stream.c,v 1.13 2003/10/21 09:02:50 petrov Exp $        */
    2 
    3 /*-
    4  * Copyright (c) 1994 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Christos Zoulas.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. All advertising materials mentioning features or use of this software
   19  *    must display the following acknowledgement:
   20  *        This product includes software developed by the NetBSD
   21  *        Foundation, Inc. and its contributors.
   22  * 4. Neither the name of The NetBSD Foundation nor the names of its
   23  *    contributors may be used to endorse or promote products derived
   24  *    from this software without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   27  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   28  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   29  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   30  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   31  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   32  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   33  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   34  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   35  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   36  * POSSIBILITY OF SUCH DAMAGE.
   37  */
   38 
   39 /*
   40  * Pretend that we have streams...
   41  * Yes, this is gross.
   42  *
   43  * ToDo: The state machine for getmsg needs re-thinking
   44  */
   45 
   46 #include <sys/cdefs.h>
   47 __KERNEL_RCSID(0, "$NetBSD: svr4_32_stream.c,v 1.13 2003/10/21 09:02:50 petrov Exp $");
   48 
   49 #include <sys/param.h>
   50 #include <sys/kernel.h>
   51 #include <sys/systm.h>
   52 #include <sys/buf.h>
   53 #include <sys/malloc.h>
   54 #include <sys/ioctl.h>
   55 #include <sys/tty.h>
   56 #include <sys/file.h>
   57 #include <sys/filedesc.h>
   58 #include <sys/select.h>
   59 #include <sys/socket.h>
   60 #include <sys/socketvar.h>
   61 #include <sys/un.h>
   62 #include <net/if.h>
   63 #include <netinet/in.h>
   64 #include <sys/mount.h>
   65 #include <sys/proc.h>
   66 #include <sys/vnode.h>
   67 #include <sys/device.h>
   68 #include <sys/stat.h>
   69 
   70 #include <sys/sa.h>
   71 #include <sys/syscallargs.h>
   72 
   73 #include <compat/svr4_32/svr4_32_types.h>
   74 #include <compat/svr4_32/svr4_32_util.h>
   75 #include <compat/svr4_32/svr4_32_signal.h>
   76 #include <compat/svr4_32/svr4_32_lwp.h>
   77 #include <compat/svr4_32/svr4_32_ucontext.h>
   78 #include <compat/svr4_32/svr4_32_syscallargs.h>
   79 #include <compat/svr4_32/svr4_32_stropts.h>
   80 #include <compat/svr4_32/svr4_32_timod.h>
   81 #include <compat/svr4/svr4_sockmod.h>
   82 #include <compat/svr4_32/svr4_32_ioctl.h>
   83 #include <compat/svr4_32/svr4_32_socket.h>
   84 
   85 
   86 /* Utils */
   87 static int clean_pipe __P((struct lwp *, const char *));
   88 static void getparm __P((struct file *, struct svr4_si_sockparms *));
   89 
   90 /* Address Conversions */
   91 static void sockaddr_to_netaddr_in __P((struct svr4_32_strmcmd *,
   92                                         const struct sockaddr_in *));
   93 static void sockaddr_to_netaddr_un __P((struct svr4_32_strmcmd *,
   94                                         const struct sockaddr_un *));
   95 static void netaddr_to_sockaddr_in __P((struct sockaddr_in *,
   96                                         const struct svr4_32_strmcmd *));
   97 static void netaddr_to_sockaddr_un __P((struct sockaddr_un *,
   98                                         const struct svr4_32_strmcmd *));
   99 
  100 /* stream ioctls */
  101 static int i_nread __P((struct file *, struct lwp *, register_t *, int,
  102     u_long, caddr_t));
  103 static int i_fdinsert __P((struct file *, struct lwp *, register_t *, int,
  104     u_long, caddr_t));
  105 static int i_str __P((struct file *, struct lwp *, register_t *, int,
  106     u_long, caddr_t));
  107 static int i_setsig __P((struct file *, struct lwp *, register_t *, int,
  108     u_long, caddr_t));
  109 static int i_getsig __P((struct file *, struct lwp *, register_t *, int,
  110     u_long, caddr_t));
  111 static int _i_bind_rsvd __P((struct file *, struct lwp *, register_t *, int,
  112     u_long, caddr_t));
  113 static int _i_rele_rsvd __P((struct file *, struct lwp *, register_t *, int,
  114     u_long, caddr_t));
  115 
  116 
  117 /* i_str sockmod calls */
  118 static int sockmod       __P((struct file *, int, struct svr4_32_strioctl *,
  119                               struct lwp *));
  120 static int si_listen     __P((struct file *, int, struct svr4_32_strioctl *,
  121                               struct lwp *));
  122 static int si_ogetudata  __P((struct file *, int, struct svr4_32_strioctl *,
  123                               struct lwp *));
  124 static int si_sockparams __P((struct file *, int, struct svr4_32_strioctl *,
  125                               struct lwp *));
  126 static int si_shutdown   __P((struct file *, int, struct svr4_32_strioctl *,
  127                               struct lwp *));
  128 static int si_getudata   __P((struct file *, int, struct svr4_32_strioctl *,
  129                               struct lwp *));
  130 
  131 /* i_str timod calls */
  132 static int timod         __P((struct file *, int, struct svr4_32_strioctl *,
  133                               struct lwp *));
  134 static int ti_getinfo    __P((struct file *, int, struct svr4_32_strioctl *,
  135                               struct lwp *));
  136 static int ti_bind       __P((struct file *, int, struct svr4_32_strioctl *,
  137                               struct lwp *));
  138 
  139 #ifdef DEBUG_SVR4
  140 static void bufprint __P((u_char *, size_t));
  141 static int show_ioc __P((const char *, struct svr4_32_strioctl *));
  142 static int show_strbuf __P((struct svr4_32_strbuf *));
  143 static void show_msg __P((const char *, int, struct svr4_32_strbuf *, 
  144                           struct svr4_32_strbuf *, int));
  145 
  146 static void
  147 bufprint(buf, len)
  148         u_char *buf;
  149         size_t len;
  150 {
  151         size_t i;
  152 
  153         uprintf("\n\t");
  154         for (i = 0; i < len; i++) {
  155                 uprintf("%x ", buf[i]);
  156                 if (i && (i % 16) == 0) 
  157                         uprintf("\n\t");
  158         }
  159 }
  160 
  161 static int
  162 show_ioc(str, ioc)
  163         const char              *str;
  164         struct svr4_32_strioctl *ioc;
  165 {
  166         u_char *ptr;
  167         int error;
  168 
  169         len = ioc->len;
  170         if (len > 1024)
  171                 len = 1024;
  172 
  173         ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK); 
  174         uprintf("%s cmd = %ld, timeout = %d, len = %d, buf = %p { ",
  175             str, ioc->cmd, ioc->timeout, ioc->len, ioc->buf);
  176 
  177         if ((error = copyin(ioc->buf, ptr, len)) != 0) {
  178                 free((char *) ptr, M_TEMP);
  179                 return error;
  180         }
  181 
  182         bufprint(ptr, len);
  183 
  184         uprintf("}\n");
  185 
  186         free((char *) ptr, M_TEMP);
  187         return 0;
  188 }
  189 
  190 
  191 static int
  192 show_strbuf(str)
  193         struct svr4_32_strbuf *str;
  194 {
  195         int error;
  196         u_char *ptr = NULL;
  197         int maxlen = str->maxlen;
  198         int len = str->len;
  199 
  200         if (maxlen > 8192)
  201                 maxlen = 8192;
  202         
  203         if (maxlen < 0)
  204                 maxlen = 0;
  205 
  206         if (len >= maxlen)
  207                 len = maxlen;
  208 
  209         if (len > 0) {
  210             ptr = (u_char *) malloc(len, M_TEMP, M_WAITOK);
  211 
  212             if ((error = copyin(str->buf, ptr, len)) != 0) {
  213                     free((char *) ptr, M_TEMP);
  214                     return error;
  215             }
  216         }
  217 
  218         uprintf(", { %d, %d, %p=[ ", str->maxlen, str->len, str->buf);
  219 
  220         if (ptr)
  221                 bufprint(ptr, len);
  222 
  223         uprintf("]}");
  224 
  225         if (ptr)
  226                 free((char *) ptr, M_TEMP);
  227 
  228         return 0;
  229 }
  230 
  231 
  232 static void
  233 show_msg(str, fd, ctl, dat, flags)
  234         const char              *str;
  235         int                      fd;
  236         struct svr4_32_strbuf   *ctl;
  237         struct svr4_32_strbuf   *dat;
  238         int                      flags;
  239 {
  240         struct svr4_32_strbuf   buf;
  241         int error;
  242 
  243         uprintf("%s(%d", str, fd);
  244         if (ctl != NULL) {
  245                 if ((error = copyin(ctl, &buf, sizeof(buf))) != 0)
  246                         return;
  247                 show_strbuf(&buf);
  248         }
  249         else 
  250                 uprintf(", NULL");
  251 
  252         if (dat != NULL) {
  253                 if ((error = copyin(dat, &buf, sizeof(buf))) != 0)
  254                         return;
  255                 show_strbuf(&buf);
  256         }
  257         else 
  258                 uprintf(", NULL");
  259 
  260         uprintf(", %x);\n", flags);
  261 }
  262 
  263 #endif /* DEBUG_SVR4 */
  264 
  265 
  266 /*
  267  * We are faced with an interesting situation. On svr4 unix sockets
  268  * are really pipes. But we really have sockets, and we might as
  269  * well use them. At the point where svr4 calls TI_BIND, it has
  270  * already created a named pipe for the socket using mknod(2).
  271  * We need to create a socket with the same name when we bind,
  272  * so we need to remove the pipe before, otherwise we'll get address
  273  * already in use. So we *carefully* remove the pipe, to avoid
  274  * using this as a random file removal tool. We use system calls
  275  * to avoid code duplication.
  276  */
  277 static int
  278 clean_pipe(l, path)
  279         struct lwp *l;
  280         const char *path;
  281 {
  282         struct sys___lstat13_args la;
  283         struct proc *p = l->l_proc;
  284         struct sys_unlink_args ua;
  285         register_t retval;
  286         struct stat st;
  287         int error;
  288         caddr_t sg = stackgap_init(p, 0);
  289         size_t len = strlen(path) + 1;
  290         void *tpath;
  291 
  292         tpath = stackgap_alloc(p, &sg, len);
  293         SCARG(&la, ub) = stackgap_alloc(p, &sg, sizeof(struct stat));
  294 
  295         if ((error = copyout(path, tpath, len)) != 0)
  296                 return error;
  297 
  298         SCARG(&la, path) = tpath;
  299 
  300         if ((error = sys___lstat13(l, &la, &retval)) != 0)
  301                 return 0;
  302 
  303         if ((error = copyin(SCARG(&la, ub), &st, sizeof(st))) != 0)
  304                 return 0;
  305 
  306         /*
  307          * Make sure we are dealing with a mode 0 named pipe.
  308          */
  309         if ((st.st_mode & S_IFMT) != S_IFIFO)
  310                 return 0;
  311 
  312         if ((st.st_mode & ALLPERMS) != 0)
  313                 return 0;
  314 
  315         SCARG(&ua, path) = SCARG(&la, path);
  316 
  317         if ((error = sys_unlink(l, &ua, &retval)) != 0) {
  318                 DPRINTF(("clean_pipe: unlink failed %d\n", error));
  319                 return error;
  320         }
  321 
  322         return 0;
  323 }
  324 
  325 static void
  326 sockaddr_to_netaddr_in(sc, sain)
  327         struct svr4_32_strmcmd *sc;
  328         const struct sockaddr_in *sain;
  329 {
  330         struct svr4_32_netaddr_in *na;
  331         na = SVR4_ADDROF(sc);
  332 
  333         na->family = sain->sin_family;
  334         na->port = sain->sin_port;
  335         na->addr = sain->sin_addr.s_addr;
  336         DPRINTF(("sockaddr_in -> netaddr %d %d %lx\n", na->family, na->port,
  337                  na->addr));
  338 }
  339 
  340 
  341 static void
  342 sockaddr_to_netaddr_un(sc, saun)
  343         struct svr4_32_strmcmd *sc;
  344         const struct sockaddr_un *saun;
  345 {
  346         struct svr4_32_netaddr_un *na;
  347         char *dst, *edst = ((char *) sc) + sc->offs + sizeof(na->family) + 1  -
  348             sizeof(*sc);
  349         const char *src;
  350 
  351         na = SVR4_ADDROF(sc);
  352         na->family = saun->sun_family;
  353         for (src = saun->sun_path, dst = na->path; (*dst++ = *src++) != '\0'; )
  354                 if (dst == edst)
  355                         break;
  356         DPRINTF(("sockaddr_un -> netaddr %d %s\n", na->family, na->path));
  357 }
  358 
  359 
  360 static void
  361 netaddr_to_sockaddr_in(sain, sc)
  362         struct sockaddr_in *sain;
  363         const struct svr4_32_strmcmd *sc;
  364 {
  365         const struct svr4_32_netaddr_in *na;
  366 
  367 
  368         na = SVR4_C_ADDROF(sc);
  369         memset(sain, 0, sizeof(*sain));
  370         sain->sin_len = sizeof(*sain);
  371         sain->sin_family = na->family;
  372         sain->sin_port = na->port;
  373         sain->sin_addr.s_addr = na->addr;
  374         DPRINTF(("netaddr -> sockaddr_in %d %d %x\n", sain->sin_family,
  375                  sain->sin_port, sain->sin_addr.s_addr));
  376 }
  377 
  378 
  379 static void
  380 netaddr_to_sockaddr_un(saun, sc)
  381         struct sockaddr_un *saun;
  382         const struct svr4_32_strmcmd *sc;
  383 {
  384         const struct svr4_32_netaddr_un *na;
  385         char *dst, *edst = &saun->sun_path[sizeof(saun->sun_path) - 1];
  386         const char *src;
  387 
  388         na = SVR4_C_ADDROF(sc);
  389         memset(saun, 0, sizeof(*saun));
  390         saun->sun_family = na->family;
  391         for (src = na->path, dst = saun->sun_path; (*dst++ = *src++) != '\0'; )
  392                 if (dst == edst)
  393                         break;
  394         saun->sun_len = dst - saun->sun_path;
  395         DPRINTF(("netaddr -> sockaddr_un %d %s\n", saun->sun_family,
  396                  saun->sun_path));
  397 }
  398 
  399 static void
  400 getparm(fp, pa)
  401         struct file *fp;
  402         struct svr4_si_sockparms *pa;
  403 {
  404         struct svr4_strm *st = svr4_32_stream_get(fp);
  405         struct socket *so = (struct socket *) fp->f_data;
  406 
  407         if (st == NULL)
  408                 return;
  409 
  410         pa->family = st->s_family;
  411 
  412         switch (so->so_type) {
  413         case SOCK_DGRAM:
  414                 pa->type = SVR4_T_CLTS;
  415                 pa->protocol = IPPROTO_UDP;
  416                 DPRINTF(("getparm(dgram)\n"));
  417                 return;
  418 
  419         case SOCK_STREAM:
  420                 pa->type = SVR4_T_COTS;  /* What about T_COTS_ORD? XXX */
  421                 pa->protocol = IPPROTO_IP;
  422                 DPRINTF(("getparm(stream)\n"));
  423                 return;
  424 
  425         case SOCK_RAW:
  426                 pa->type = SVR4_T_CLTS;
  427                 pa->protocol = IPPROTO_RAW;
  428                 DPRINTF(("getparm(raw)\n"));
  429                 return;
  430 
  431         default:
  432                 pa->type = 0;
  433                 pa->protocol = 0;
  434                 DPRINTF(("getparm(type %d?)\n", so->so_type));
  435                 return;
  436         }
  437 }
  438 
  439 static int
  440 si_ogetudata(fp, fd, ioc, l)
  441         struct file             *fp;
  442         int                      fd;
  443         struct svr4_32_strioctl *ioc;
  444         struct lwp              *l;
  445 {
  446         int error;
  447         struct svr4_si_oudata ud;
  448         struct svr4_si_sockparms pa;
  449 
  450         if (ioc->len != sizeof(ud) && ioc->len != sizeof(ud) - sizeof(int)) {
  451                 DPRINTF(("SI_OGETUDATA: Wrong size %ld != %d\n",
  452                     (unsigned long)sizeof(ud), ioc->len));
  453                 return EINVAL;
  454         }
  455 
  456         if ((error = copyin((caddr_t)(u_long)ioc->buf, &ud, sizeof(ud))) != 0)
  457                 return error;
  458 
  459         getparm(fp, &pa);
  460 
  461         switch (pa.family) {
  462         case AF_INET:
  463             ud.tidusize = 16384;
  464             ud.addrsize = sizeof(struct sockaddr_in);
  465             if (pa.type == SVR4_SOCK_STREAM) 
  466                     ud.etsdusize = 1;
  467             else
  468                     ud.etsdusize = 0;
  469             break;
  470 
  471         case AF_LOCAL:
  472             ud.tidusize = 65536;
  473             ud.addrsize = 128;
  474             ud.etsdusize = 128;
  475             break;
  476 
  477         default:
  478             DPRINTF(("SI_OGETUDATA: Unsupported address family %d\n",
  479                      pa.family));
  480             return ENOSYS;
  481         }
  482 
  483         /* I have no idea what these should be! */
  484         ud.optsize = 128;
  485         ud.tsdusize = 128;
  486 
  487         ud.servtype = pa.type;
  488 
  489         /* XXX: Fixme */
  490         ud.so_state = 0;
  491         ud.so_options = 0;
  492         return copyout(&ud, (caddr_t)(u_long)ioc->buf, ioc->len);
  493 }
  494 
  495 
  496 static int
  497 si_sockparams(fp, fd, ioc, l)
  498         struct file             *fp;
  499         int                      fd;
  500         struct svr4_32_strioctl *ioc;
  501         struct lwp              *l;
  502 {
  503         struct svr4_si_sockparms pa;
  504 
  505         getparm(fp, &pa);
  506         return copyout(&pa, (caddr_t)(u_long)ioc->buf, sizeof(pa));
  507 }
  508 
  509 
  510 static int
  511 si_listen(fp, fd, ioc, l)
  512         struct file             *fp;
  513         int                      fd;
  514         struct svr4_32_strioctl *ioc;
  515         struct lwp              *l;
  516 {
  517         int error;
  518         struct svr4_strm *st = svr4_32_stream_get(fp);
  519         register_t retval;
  520         struct svr4_32_strmcmd lst;
  521         struct sys_listen_args la;
  522 
  523         if (st == NULL)
  524                 return EINVAL;
  525 
  526         if (ioc->len > sizeof(lst))
  527                 return EINVAL;
  528 
  529         if ((error = copyin((caddr_t)(u_long)ioc->buf, &lst, ioc->len)) != 0)
  530                 return error;
  531 
  532         if (lst.cmd != SVR4_TI_OLD_BIND_REQUEST) {
  533                 DPRINTF(("si_listen: bad request %ld\n", lst.cmd));
  534                 return EINVAL;
  535         }
  536 
  537         /*
  538          * We are making assumptions again...
  539          */
  540         SCARG(&la, s) = fd;
  541         DPRINTF(("SI_LISTEN: fileno %d backlog = %d\n", fd, 5));
  542         SCARG(&la, backlog) = 5;
  543 
  544         if ((error = sys_listen(l, &la, &retval)) != 0) {
  545                 DPRINTF(("SI_LISTEN: listen failed %d\n", error));
  546                 return error;
  547         }
  548 
  549         st->s_cmd = SVR4_TI__ACCEPT_WAIT;
  550         lst.cmd = SVR4_TI_BIND_REPLY;
  551 
  552         switch (st->s_family) {
  553         case AF_INET:
  554                 /* XXX: Fill the length here */
  555                 break;
  556 
  557         case AF_LOCAL:
  558                 lst.len = 140;
  559                 lst.pad[28] = 0x00000000;       /* magic again */
  560                 lst.pad[29] = 0x00000800;       /* magic again */
  561                 lst.pad[30] = 0x80001400;       /* magic again */
  562                 break;
  563 
  564         default:
  565                 DPRINTF(("SI_LISTEN: Unsupported address family %d\n",
  566                     st->s_family));
  567                 return ENOSYS;
  568         }
  569 
  570 
  571         if ((error = copyout(&lst, (caddr_t)(u_long)ioc->buf, ioc->len)) != 0)
  572                 return error;
  573 
  574         return 0;
  575 }
  576 
  577 
  578 static int
  579 si_getudata(fp, fd, ioc, l)
  580         struct file             *fp;
  581         int                      fd;
  582         struct svr4_32_strioctl *ioc;
  583         struct lwp              *l;
  584 {
  585         int error;
  586         struct svr4_si_udata ud;
  587 
  588         if (sizeof(ud) != ioc->len) {
  589                 DPRINTF(("SI_GETUDATA: Wrong size %ld != %d\n",
  590                     (unsigned long)sizeof(ud), ioc->len));
  591                 return EINVAL;
  592         }
  593 
  594         if ((error = copyin((caddr_t)(u_long)ioc->buf, &ud, sizeof(ud))) != 0)
  595                 return error;
  596 
  597         getparm(fp, &ud.sockparms);
  598 
  599         switch (ud.sockparms.family) {
  600         case AF_INET:
  601             ud.tidusize = 16384;
  602             ud.tsdusize = 16384;
  603             ud.addrsize = sizeof(struct sockaddr_in);
  604             if (ud.sockparms.type == SVR4_SOCK_STREAM) 
  605                     ud.etsdusize = 1;
  606             else
  607                     ud.etsdusize = 0;
  608             ud.optsize = 0;
  609             break;
  610 
  611         case AF_LOCAL:
  612             ud.tidusize = 65536;
  613             ud.tsdusize = 128;
  614             ud.addrsize = 128;
  615             ud.etsdusize = 128;
  616             ud.optsize = 128;
  617             break;
  618 
  619         default:
  620             DPRINTF(("SI_GETUDATA: Unsupported address family %d\n",
  621                      ud.sockparms.family));
  622             return ENOSYS;
  623         }
  624 
  625 
  626         ud.servtype = ud.sockparms.type;
  627 
  628         /* XXX: Fixme */
  629         ud.so_state = 0;
  630         ud.so_options = 0;
  631         return copyout(&ud, (caddr_t)(u_long)ioc->buf, sizeof(ud));
  632 }
  633 
  634 
  635 static int
  636 si_shutdown(fp, fd, ioc, l)
  637         struct file             *fp;
  638         int                      fd;
  639         struct svr4_32_strioctl *ioc;
  640         struct lwp              *l;
  641 {
  642         int error;
  643         struct sys_shutdown_args ap;
  644         register_t retval;
  645 
  646         if (ioc->len != sizeof(SCARG(&ap, how))) {
  647                 DPRINTF(("SI_SHUTDOWN: Wrong size %ld != %d\n",
  648                     (unsigned long)sizeof(SCARG(&ap, how)), ioc->len));
  649                 return EINVAL;
  650         }
  651 
  652         if ((error = copyin((caddr_t)(u_long)ioc->buf, &SCARG(&ap, how), ioc->len)) != 0)
  653                 return error;
  654 
  655         SCARG(&ap, s) = fd;
  656 
  657         return sys_shutdown(l, &ap, &retval);
  658 }
  659 
  660 static int
  661 sockmod(fp, fd, ioc, l)
  662         struct file             *fp;
  663         int                      fd;
  664         struct svr4_32_strioctl *ioc;
  665         struct lwp              *l;
  666 {
  667         switch (ioc->cmd) {
  668         case SVR4_SI_OGETUDATA:
  669                 DPRINTF(("SI_OGETUDATA\n"));
  670                 return si_ogetudata(fp, fd, ioc, l);
  671 
  672         case SVR4_SI_SHUTDOWN:
  673                 DPRINTF(("SI_SHUTDOWN\n"));
  674                 return si_shutdown(fp, fd, ioc, l);
  675 
  676         case SVR4_SI_LISTEN:
  677                 DPRINTF(("SI_LISTEN\n"));
  678                 return si_listen(fp, fd, ioc, l);
  679 
  680         case SVR4_SI_SETMYNAME:
  681                 DPRINTF(("SI_SETMYNAME\n"));
  682                 return 0;
  683 
  684         case SVR4_SI_SETPEERNAME:
  685                 DPRINTF(("SI_SETPEERNAME\n"));
  686                 return 0;
  687 
  688         case SVR4_SI_GETINTRANSIT:
  689                 DPRINTF(("SI_GETINTRANSIT\n"));
  690                 return 0;
  691 
  692         case SVR4_SI_TCL_LINK:
  693                 DPRINTF(("SI_TCL_LINK\n"));
  694                 return 0;
  695 
  696         case SVR4_SI_TCL_UNLINK:
  697                 DPRINTF(("SI_TCL_UNLINK\n"));
  698                 return 0;
  699 
  700         case SVR4_SI_SOCKPARAMS:
  701                 DPRINTF(("SI_SOCKPARAMS\n"));
  702                 return si_sockparams(fp, fd, ioc, l);
  703 
  704         case SVR4_SI_GETUDATA:
  705                 DPRINTF(("SI_GETUDATA\n"));
  706                 return si_getudata(fp, fd, ioc, l);
  707 
  708         default:
  709                 DPRINTF(("Unknown sockmod ioctl %lx\n", ioc->cmd));
  710                 return 0;
  711 
  712         }
  713 }
  714 
  715 static int
  716 ti_getinfo(fp, fd, ioc, l)
  717         struct file             *fp;
  718         int                      fd;
  719         struct svr4_32_strioctl *ioc;
  720         struct lwp              *l;
  721 {
  722         int error;
  723         struct svr4_32_infocmd info;
  724 
  725         memset(&info, 0, sizeof(info));
  726 
  727         if (ioc->len > sizeof(info))
  728                 return EINVAL;
  729         
  730         if ((error = copyin((caddr_t)(u_long)ioc->buf, &info, ioc->len)) != 0)
  731                 return error;
  732 
  733         if (info.cmd != SVR4_TI_INFO_REQUEST)
  734                 return EINVAL;
  735 
  736         info.cmd = SVR4_TI_INFO_REPLY;
  737         info.tsdu = 0;
  738         info.etsdu = 1;
  739         info.cdata = -2;
  740         info.ddata = -2;
  741         info.addr = 16;
  742         info.opt = -1;
  743         info.tidu = 16384;
  744         info.serv = 2;
  745         info.current = 0;
  746         info.provider = 2;
  747 
  748         ioc->len = sizeof(info);
  749         if ((error = copyout(&info, (caddr_t)(u_long)ioc->buf, ioc->len)) != 0)
  750                 return error;
  751 
  752         return 0;
  753 }
  754 
  755 
  756 static int
  757 ti_bind(fp, fd, ioc, l)
  758         struct file             *fp;
  759         int                      fd;
  760         struct svr4_32_strioctl *ioc;
  761         struct lwp              *l;
  762 {
  763         int error;
  764         struct proc *p = l->l_proc;
  765         struct svr4_strm *st = svr4_32_stream_get(fp);
  766         struct sockaddr_in sain;
  767         struct sockaddr_un saun;
  768         register_t retval;
  769         caddr_t sg;
  770         void *skp, *sup = NULL;
  771         int sasize;
  772         struct svr4_32_strmcmd bnd;
  773         struct sys_bind_args ba;
  774 
  775         if (st == NULL) {
  776                 DPRINTF(("ti_bind: bad file descriptor\n"));
  777                 return EINVAL;
  778         }
  779 
  780         if (ioc->len > sizeof(bnd))
  781                 return EINVAL;
  782         
  783         if ((error = copyin((caddr_t)(u_long)ioc->buf, &bnd, ioc->len)) != 0)
  784                 return error;
  785 
  786         if (bnd.cmd != SVR4_TI_OLD_BIND_REQUEST) {
  787                 DPRINTF(("ti_bind: bad request %ld\n", bnd.cmd));
  788                 return EINVAL;
  789         }
  790 
  791         switch (st->s_family) {
  792         case AF_INET:
  793                 skp = &sain;
  794                 sasize = sizeof(sain);
  795 
  796                 if (bnd.offs == 0)
  797                         goto reply;
  798 
  799                 netaddr_to_sockaddr_in(&sain, &bnd);
  800 
  801                 DPRINTF(("TI_BIND: fam %d, port %d, addr %x\n",
  802                          sain.sin_family, sain.sin_port,
  803                          sain.sin_addr.s_addr));
  804                 break;
  805 
  806         case AF_LOCAL:
  807                 skp = &saun;
  808                 sasize = sizeof(saun);
  809                 if (bnd.offs == 0)
  810                         goto reply;
  811 
  812                 netaddr_to_sockaddr_un(&saun, &bnd);
  813 
  814                 if (saun.sun_path[0] == '\0')
  815                         goto reply;
  816 
  817                 DPRINTF(("TI_BIND: fam %d, path %s\n",
  818                          saun.sun_family, saun.sun_path));
  819 
  820                 if ((error = clean_pipe(l, saun.sun_path)) != 0)
  821                         return error;
  822 
  823                 bnd.pad[28] = 0x00001000;       /* magic again */
  824                 break;
  825 
  826         default:
  827                 DPRINTF(("TI_BIND: Unsupported address family %d\n",
  828                          st->s_family));
  829                 return ENOSYS;
  830         }
  831 
  832         sg = stackgap_init(p, 0);
  833         sup = stackgap_alloc(p, &sg, sasize);
  834 
  835         if ((error = copyout(skp, sup, sasize)) != 0)
  836                 return error;
  837 
  838         SCARG(&ba, s) = fd;
  839         DPRINTF(("TI_BIND: fileno %d\n", fd));
  840         SCARG(&ba, name) = (void *) sup;
  841         SCARG(&ba, namelen) = sasize;
  842 
  843         if ((error = sys_bind(l, &ba, &retval)) != 0) {
  844                 DPRINTF(("TI_BIND: bind failed %d\n", error));
  845                 return error;
  846         }
  847 
  848 reply:
  849         if (sup == NULL) {
  850                 memset(&bnd, 0, sizeof(bnd));
  851                 bnd.len = sasize + 4;
  852                 bnd.offs = 0x10;        /* XXX */
  853         }
  854 
  855         bnd.cmd = SVR4_TI_BIND_REPLY;
  856 
  857         if ((error = copyout(&bnd, (caddr_t)(u_long)ioc->buf, ioc->len)) != 0)
  858                 return error;
  859 
  860         return 0;
  861 }
  862 
  863 
  864 static int
  865 timod(fp, fd, ioc, l)
  866         struct file             *fp;
  867         int                      fd;
  868         struct svr4_32_strioctl *ioc;
  869         struct lwp              *l;
  870 {
  871         switch (ioc->cmd) {
  872         case SVR4_TI_GETINFO:
  873                 DPRINTF(("TI_GETINFO\n"));
  874                 return ti_getinfo(fp, fd, ioc, l);
  875 
  876         case SVR4_TI_OPTMGMT:
  877                 DPRINTF(("TI_OPTMGMT\n"));
  878                 return 0;
  879 
  880         case SVR4_TI_BIND:
  881                 DPRINTF(("TI_BIND\n"));
  882                 return ti_bind(fp, fd, ioc, l);
  883 
  884         case SVR4_TI_UNBIND:
  885                 DPRINTF(("TI_UNBIND\n"));
  886                 return 0;
  887 
  888         default:
  889                 DPRINTF(("Unknown timod ioctl %lx\n", ioc->cmd));
  890                 return 0;
  891         }
  892 }
  893 
  894 int
  895 svr4_32_stream_ti_ioctl(fp, l, retval, fd, cmd, dat)
  896         struct file *fp;
  897         struct lwp *l;
  898         register_t *retval;
  899         int fd;
  900         u_long cmd;
  901         caddr_t dat;
  902 {
  903         struct proc *p = l->l_proc;
  904         struct svr4_32_strbuf skb, *sub = (struct svr4_32_strbuf *) dat;
  905         struct svr4_strm *st = svr4_32_stream_get(fp);
  906         int error;
  907         void *skp, *sup;
  908         struct sockaddr_in sain;
  909         struct sockaddr_un saun;
  910         struct svr4_32_strmcmd sc;
  911         int sasize;
  912         caddr_t sg;
  913         int *lenp;
  914 
  915         if (st == NULL)
  916                 return EINVAL;
  917 
  918         sc.offs = 0x10;
  919         
  920         if ((error = copyin(sub, &skb, sizeof(skb))) != 0) {
  921                 DPRINTF(("ti_ioctl: error copying in strbuf\n"));
  922                 return error;
  923         }
  924 
  925         switch (st->s_family) {
  926         case AF_INET:
  927                 skp = &sain;
  928                 sasize = sizeof(sain);
  929                 break;
  930 
  931         case AF_LOCAL:
  932                 skp = &saun;
  933                 sasize = sizeof(saun);
  934                 break;
  935 
  936         default:
  937                 DPRINTF(("ti_ioctl: Unsupported address family %d\n",
  938                          st->s_family));
  939                 return ENOSYS;
  940         }
  941 
  942         sg = stackgap_init(p, 0);
  943         sup = stackgap_alloc(p, &sg, sasize);
  944         lenp = stackgap_alloc(p, &sg, sizeof(*lenp));
  945 
  946         if ((error = copyout(&sasize, lenp, sizeof(*lenp))) != 0) {
  947                 DPRINTF(("ti_ioctl: error copying out lenp\n"));
  948                 return error;
  949         }
  950 
  951         switch (cmd) {
  952         case SVR4_TI_GETMYNAME:
  953                 DPRINTF(("TI_GETMYNAME\n"));
  954                 {
  955                         struct sys_getsockname_args ap;
  956                         SCARG(&ap, fdes) = fd;
  957                         SCARG(&ap, asa) = sup;
  958                         SCARG(&ap, alen) = lenp;
  959                         if ((error = sys_getsockname(l, &ap, retval)) != 0) {
  960                                 DPRINTF(("ti_ioctl: getsockname error\n"));
  961                                 return error;
  962                         }
  963                 }
  964                 break;
  965 
  966         case SVR4_TI_GETPEERNAME:
  967                 DPRINTF(("TI_GETPEERNAME\n"));
  968                 {
  969                         struct sys_getpeername_args ap;
  970                         SCARG(&ap, fdes) = fd;
  971                         SCARG(&ap, asa) = sup;
  972                         SCARG(&ap, alen) = lenp;
  973                         if ((error = sys_getpeername(l, &ap, retval)) != 0) {
  974                                 DPRINTF(("ti_ioctl: getpeername error\n"));
  975                                 return error;
  976                         }
  977                 }
  978                 break;
  979 
  980         case SVR4_TI_SETMYNAME:
  981                 DPRINTF(("TI_SETMYNAME\n"));
  982                 return 0;
  983 
  984         case SVR4_TI_SETPEERNAME:
  985                 DPRINTF(("TI_SETPEERNAME\n"));
  986                 return 0;
  987         default:
  988                 DPRINTF(("ti_ioctl: Unknown ioctl %lx\n", cmd));
  989                 return ENOSYS;
  990         }
  991 
  992         if ((error = copyin(sup, skp, sasize)) != 0) {
  993                 DPRINTF(("ti_ioctl: error copying in socket data\n"));
  994                 return error;
  995         }
  996 
  997         if ((error = copyin(lenp, &sasize, sizeof(*lenp))) != 0) {
  998                 DPRINTF(("ti_ioctl: error copying in socket size\n"));
  999                 return error;
 1000         }
 1001 
 1002         switch (st->s_family) {
 1003         case AF_INET:
 1004                 sockaddr_to_netaddr_in(&sc, &sain);
 1005                 skb.len = sasize;
 1006                 break;
 1007 
 1008         case AF_LOCAL:
 1009                 sockaddr_to_netaddr_un(&sc, &saun);
 1010                 skb.len = sasize + 4;
 1011                 break;
 1012 
 1013         default:
 1014                 return ENOSYS;
 1015         }
 1016 
 1017 
 1018         if ((error = copyout(SVR4_ADDROF(&sc), (caddr_t)(u_long)skb.buf, 
 1019                              sasize)) != 0) {
 1020                 DPRINTF(("ti_ioctl: error copying out socket data\n"));
 1021                 return error;
 1022         }
 1023 
 1024 
 1025         if ((error = copyout(&skb, sub, sizeof(skb))) != 0) {
 1026                 DPRINTF(("ti_ioctl: error copying out strbuf\n"));
 1027                 return error;
 1028         }
 1029 
 1030         return error;
 1031 }
 1032 
 1033 
 1034 static int
 1035 i_nread(fp, l, retval, fd, cmd, dat)
 1036         struct file *fp;
 1037         struct lwp *l;
 1038         register_t *retval;
 1039         int fd;
 1040         u_long cmd;
 1041         caddr_t dat;
 1042 {
 1043         int error;
 1044         int nread = 0;  
 1045 
 1046         /*
 1047          * We are supposed to return the message length in nread, and the
 1048          * number of messages in retval. We don't have the notion of number
 1049          * of stream messages, so we just find out if we have any bytes waiting
 1050          * for us, and if we do, then we assume that we have at least one
 1051          * message waiting for us.
 1052          */
 1053         if ((error = (*fp->f_ops->fo_ioctl)(fp, FIONREAD,
 1054             (caddr_t) &nread, l->l_proc)) != 0)
 1055                 return error;
 1056 
 1057         if (nread != 0)
 1058                 *retval = 1;
 1059         else
 1060                 *retval = 0;
 1061 
 1062         return copyout(&nread, dat, sizeof(nread));
 1063 }
 1064 
 1065 static int
 1066 i_fdinsert(fp, l, retval, fd, cmd, dat)
 1067         struct file *fp;
 1068         struct lwp *l;
 1069         register_t *retval;
 1070         int fd;
 1071         u_long cmd;
 1072         caddr_t dat;
 1073 {
 1074         /*
 1075          * Major hack again here. We assume that we are using this to
 1076          * implement accept(2). If that is the case, we have already
 1077          * called accept, and we have stored the file descriptor in
 1078          * afd. We find the file descriptor that the code wants to use
 1079          * in fd insert, and then we dup2() our accepted file descriptor
 1080          * to it.
 1081          */
 1082         int error;
 1083         struct svr4_strm *st = svr4_32_stream_get(fp);
 1084         struct svr4_32_strfdinsert fdi;
 1085         struct sys_dup2_args d2p;
 1086         struct sys_close_args clp;
 1087 
 1088         if (st == NULL) {
 1089                 DPRINTF(("fdinsert: bad file type\n"));
 1090                 return EINVAL;
 1091         }
 1092 
 1093         if (st->s_afd == -1) {
 1094                 DPRINTF(("fdinsert: accept fd not found\n"));
 1095                 return ENOENT;
 1096         }
 1097 
 1098         if ((error = copyin(dat, &fdi, sizeof(fdi))) != 0) {
 1099                 DPRINTF(("fdinsert: copyin failed %d\n", error));
 1100                 return error;
 1101         }
 1102 
 1103         SCARG(&d2p, from) = st->s_afd;
 1104         SCARG(&d2p, to) = fdi.fd;
 1105 
 1106         if ((error = sys_dup2(l, &d2p, retval)) != 0) {
 1107                 DPRINTF(("fdinsert: dup2(%d, %d) failed %d\n", 
 1108                     st->s_afd, fdi.fd, error));
 1109                 return error;
 1110         }
 1111 
 1112         SCARG(&clp, fd) = st->s_afd;
 1113 
 1114         if ((error = sys_close(l, &clp, retval)) != 0) {
 1115                 DPRINTF(("fdinsert: close(%d) failed %d\n", 
 1116                     st->s_afd, error));
 1117                 return error;
 1118         }
 1119 
 1120         st->s_afd = -1;
 1121 
 1122         *retval = 0;
 1123         return 0;
 1124 }
 1125 
 1126 
 1127 static int
 1128 _i_bind_rsvd(fp, l, retval, fd, cmd, dat)
 1129         struct file *fp;
 1130         struct lwp *l;
 1131         register_t *retval;
 1132         int fd;
 1133         u_long cmd;
 1134         caddr_t dat;
 1135 {
 1136         struct sys_mknod_args ap;
 1137 
 1138         /*
 1139          * This is a supposed to be a kernel and library only ioctl.
 1140          * It gets called before ti_bind, when we have a unix 
 1141          * socket, to physically create the socket transport and
 1142          * ``reserve'' it. I don't know how this get reserved inside
 1143          * the kernel, but we are going to create it nevertheless.
 1144          */
 1145         SCARG(&ap, path) = dat;
 1146         SCARG(&ap, mode) = S_IFIFO;
 1147 
 1148         return sys_mkfifo(l, &ap, retval);
 1149 }
 1150 
 1151 static int
 1152 _i_rele_rsvd(fp, l, retval, fd, cmd, dat)
 1153         struct file *fp;
 1154         struct lwp *l;
 1155         register_t *retval;
 1156         int fd;
 1157         u_long cmd;
 1158         caddr_t dat;
 1159 {
 1160         struct sys_unlink_args ap;
 1161 
 1162         /*
 1163          * This is a supposed to be a kernel and library only ioctl.
 1164          * I guess it is supposed to release the socket.
 1165          */
 1166         SCARG(&ap, path) = dat;
 1167 
 1168         return sys_unlink(l, &ap, retval);
 1169 }
 1170 
 1171 static int
 1172 i_str(fp, l, retval, fd, cmd, dat)
 1173         struct file *fp;
 1174         struct lwp *l;
 1175         register_t *retval;
 1176         int fd;
 1177         u_long cmd;
 1178         caddr_t dat;
 1179 {
 1180         int                      error;
 1181         struct svr4_32_strioctl  ioc;
 1182 
 1183         /*
 1184          * Noop on non sockets
 1185          */
 1186         if (fp->f_type != DTYPE_SOCKET)
 1187                 return 0;
 1188 
 1189         if ((error = copyin(dat, &ioc, sizeof(ioc))) != 0)
 1190                 return error;
 1191 
 1192 #ifdef DEBUG_SVR4
 1193         if ((error = show_ioc(">", &ioc)) != 0)
 1194                 return error;
 1195 #endif /* DEBUG_SVR4 */
 1196 
 1197         switch (ioc.cmd & 0xff00) {
 1198         case SVR4_SIMOD:
 1199                 if ((error = sockmod(fp, fd, &ioc, l)) != 0)
 1200                         return error;
 1201                 break;
 1202 
 1203         case SVR4_TIMOD:
 1204                 if ((error = timod(fp, fd, &ioc, l)) != 0)
 1205                         return error;
 1206                 break;
 1207 
 1208         default:
 1209                 DPRINTF(("Unimplemented module %c %ld\n",
 1210                          (char) (cmd >> 8), cmd & 0xff));
 1211                 return 0;
 1212         }
 1213 
 1214 #ifdef DEBUG_SVR4
 1215         if ((error = show_ioc("<", &ioc)) != 0)
 1216                 return error;
 1217 #endif /* DEBUG_SVR4 */
 1218         return copyout(&ioc, dat, sizeof(ioc));
 1219 }
 1220 
 1221 static int
 1222 i_setsig(fp, l, retval, fd, cmd, dat)
 1223         struct file *fp;
 1224         struct lwp *l;
 1225         register_t *retval;
 1226         int fd;
 1227         u_long cmd;
 1228         caddr_t dat;
 1229 {
 1230         /* 
 1231          * This is the best we can do for now; we cannot generate
 1232          * signals only for specific events so the signal mask gets
 1233          * ignored; we save it just to pass it to a possible I_GETSIG...
 1234          *
 1235          * We alse have to fix the O_ASYNC fcntl bit, so the
 1236          * process will get SIGPOLLs.
 1237          */
 1238         struct sys_fcntl_args fa;
 1239         int error;
 1240         register_t oflags, flags;
 1241         struct svr4_strm *st = svr4_32_stream_get(fp);
 1242 
 1243         if (st == NULL) {
 1244                 DPRINTF(("i_setsig: bad file descriptor\n"));
 1245                 return EINVAL;
 1246         }
 1247         /* get old status flags */
 1248         SCARG(&fa, fd) = fd;
 1249         SCARG(&fa, cmd) = F_GETFL;
 1250         if ((error = sys_fcntl(l, &fa, &oflags)) != 0)
 1251                 return error;
 1252 
 1253         /* update the flags */
 1254         if (dat != NULL) {
 1255                 int mask;
 1256 
 1257                 flags = oflags | O_ASYNC;
 1258                 mask = (int)(u_long)dat;
 1259                 if (mask & ~SVR4_S_ALLMASK) {
 1260                         DPRINTF(("i_setsig: bad eventmask data %x\n", mask));
 1261                         return EINVAL;
 1262                 }
 1263                 st->s_eventmask = mask;
 1264         }
 1265         else {
 1266                 flags = oflags & ~O_ASYNC;
 1267                 st->s_eventmask = 0;
 1268         }
 1269 
 1270         /* set the new flags, if changed */
 1271         if (flags != oflags) {
 1272                 SCARG(&fa, cmd) = F_SETFL;
 1273                 SCARG(&fa, arg) = (void *) flags;
 1274                 if ((error = sys_fcntl(l, &fa, &flags)) != 0)
 1275                         return error;
 1276         }
 1277 
 1278         /* set up SIGIO receiver if needed */
 1279         if (dat != NULL) {
 1280                 SCARG(&fa, cmd) = F_SETOWN;
 1281                 SCARG(&fa, arg) = (void *)(u_long)l->l_proc->p_pid;
 1282                 return sys_fcntl(l, &fa, &flags);
 1283         }
 1284         return 0;
 1285 }
 1286 
 1287 static int
 1288 i_getsig(fp, l, retval, fd, cmd, dat)
 1289         struct file *fp;
 1290         struct lwp *l;
 1291         register_t *retval;
 1292         int fd;
 1293         u_long cmd;
 1294         caddr_t dat;
 1295 {
 1296         int error;
 1297 
 1298         if (dat != NULL) {
 1299                 struct svr4_strm *st = svr4_32_stream_get(fp);
 1300 
 1301                 if (st == NULL) {
 1302                         DPRINTF(("i_getsig: bad file descriptor\n"));
 1303                         return EINVAL;
 1304                 }
 1305                 if ((error = copyout(&st->s_eventmask, dat, 
 1306                     sizeof(st->s_eventmask))) != 0) {
 1307                         DPRINTF(("i_getsig: bad eventmask pointer\n"));
 1308                         return error;
 1309                 }
 1310         }
 1311         return 0;
 1312 }
 1313 
 1314 int
 1315 svr4_32_stream_ioctl(fp, l, retval, fd, cmd, dat)
 1316         struct file *fp;
 1317         struct lwp *l;
 1318         register_t *retval;
 1319         int fd;
 1320         u_long cmd;
 1321         caddr_t dat;
 1322 {
 1323         *retval = 0;
 1324         /*
 1325          * All the following stuff assumes "sockmod" is pushed...
 1326          */
 1327         switch (cmd) {
 1328         case SVR4_I_NREAD:
 1329                 DPRINTF(("I_NREAD\n"));
 1330                 return i_nread(fp, l, retval, fd, cmd, dat);
 1331 
 1332         case SVR4_I_PUSH:
 1333                 DPRINTF(("I_PUSH\n"));
 1334                 return 0;
 1335 
 1336         case SVR4_I_POP:
 1337                 DPRINTF(("I_POP\n"));
 1338                 return 0;
 1339 
 1340         case SVR4_I_LOOK:
 1341                 DPRINTF(("I_LOOK\n"));
 1342                 return 0;
 1343 
 1344         case SVR4_I_FLUSH:
 1345                 DPRINTF(("I_FLUSH\n"));
 1346                 return 0;
 1347 
 1348         case SVR4_I_SRDOPT:
 1349                 DPRINTF(("I_SRDOPT\n"));
 1350                 return 0;
 1351 
 1352         case SVR4_I_GRDOPT:
 1353                 DPRINTF(("I_GRDOPT\n"));
 1354                 return 0;
 1355 
 1356         case SVR4_I_STR:
 1357                 DPRINTF(("I_STR\n"));
 1358                 return i_str(fp, l, retval, fd, cmd, dat);
 1359 
 1360         case SVR4_I_SETSIG:
 1361                 DPRINTF(("I_SETSIG\n"));
 1362                 return i_setsig(fp, l, retval, fd, cmd, dat);
 1363 
 1364         case SVR4_I_GETSIG:
 1365                 DPRINTF(("I_GETSIG\n"));
 1366                 return i_getsig(fp, l, retval, fd, cmd, dat);
 1367 
 1368         case SVR4_I_FIND:
 1369                 DPRINTF(("I_FIND\n"));
 1370                 /*
 1371                  * Here we are not pushing modules really, we just
 1372                  * pretend all are present
 1373                  */
 1374                 *retval = 1;
 1375                 return 0;
 1376 
 1377         case SVR4_I_LINK:
 1378                 DPRINTF(("I_LINK\n"));
 1379                 return 0;
 1380 
 1381         case SVR4_I_UNLINK:
 1382                 DPRINTF(("I_UNLINK\n"));
 1383                 return 0;
 1384 
 1385         case SVR4_I_ERECVFD:
 1386                 DPRINTF(("I_ERECVFD\n"));
 1387                 return 0;
 1388 
 1389         case SVR4_I_PEEK:
 1390                 DPRINTF(("I_PEEK\n"));
 1391                 return 0;
 1392 
 1393         case SVR4_I_FDINSERT:
 1394                 DPRINTF(("I_FDINSERT\n"));
 1395                 return i_fdinsert(fp, l, retval, fd, cmd, dat);
 1396 
 1397         case SVR4_I_SENDFD:
 1398                 DPRINTF(("I_SENDFD\n"));
 1399                 return 0;
 1400 
 1401         case SVR4_I_RECVFD:
 1402                 DPRINTF(("I_RECVFD\n"));
 1403                 return 0;
 1404 
 1405         case SVR4_I_SWROPT:
 1406                 DPRINTF(("I_SWROPT\n"));
 1407                 return 0;
 1408 
 1409         case SVR4_I_GWROPT:
 1410                 DPRINTF(("I_GWROPT\n"));
 1411                 return 0;
 1412 
 1413         case SVR4_I_LIST:
 1414                 DPRINTF(("I_LIST\n"));
 1415                 return 0;
 1416 
 1417         case SVR4_I_PLINK:
 1418                 DPRINTF(("I_PLINK\n"));
 1419                 return 0;
 1420 
 1421         case SVR4_I_PUNLINK:
 1422                 DPRINTF(("I_PUNLINK\n"));
 1423                 return 0;
 1424 
 1425         case SVR4_I_SETEV:
 1426                 DPRINTF(("I_SETEV\n"));
 1427                 return 0;
 1428 
 1429         case SVR4_I_GETEV:
 1430                 DPRINTF(("I_GETEV\n"));
 1431                 return 0;
 1432 
 1433         case SVR4_I_STREV:
 1434                 DPRINTF(("I_STREV\n"));
 1435                 return 0;
 1436 
 1437         case SVR4_I_UNSTREV:
 1438                 DPRINTF(("I_UNSTREV\n"));
 1439                 return 0;
 1440 
 1441         case SVR4_I_FLUSHBAND:
 1442                 DPRINTF(("I_FLUSHBAND\n"));
 1443                 return 0;
 1444 
 1445         case SVR4_I_CKBAND:
 1446                 DPRINTF(("I_CKBAND\n"));
 1447                 return 0;
 1448 
 1449         case SVR4_I_GETBAND:
 1450                 DPRINTF(("I_GETBANK\n"));
 1451                 return 0;
 1452 
 1453         case SVR4_I_ATMARK:
 1454                 DPRINTF(("I_ATMARK\n"));
 1455                 return 0;
 1456 
 1457         case SVR4_I_SETCLTIME:
 1458                 DPRINTF(("I_SETCLTIME\n"));
 1459                 return 0;
 1460 
 1461         case SVR4_I_GETCLTIME:
 1462                 DPRINTF(("I_GETCLTIME\n"));
 1463                 return 0;
 1464 
 1465         case SVR4_I_CANPUT:
 1466                 DPRINTF(("I_CANPUT\n"));
 1467                 return 0;
 1468 
 1469         case SVR4__I_BIND_RSVD:
 1470                 DPRINTF(("_I_BIND_RSVD\n"));
 1471                 return _i_bind_rsvd(fp, l, retval, fd, cmd, dat);
 1472 
 1473         case SVR4__I_RELE_RSVD:
 1474                 DPRINTF(("_I_RELE_RSVD\n"));
 1475                 return _i_rele_rsvd(fp, l, retval, fd, cmd, dat);
 1476 
 1477         default:
 1478                 DPRINTF(("unimpl cmd = %lx\n", cmd));
 1479                 break;
 1480         }
 1481         return 0;
 1482 }
 1483 
 1484 
 1485 
 1486 
 1487 int
 1488 svr4_32_sys_putmsg(l, v, retval)
 1489         struct lwp *l;
 1490         void *v;
 1491         register_t *retval;
 1492 {
 1493         struct svr4_32_sys_putmsg_args *uap = v;
 1494         struct proc *p = l->l_proc;
 1495         struct filedesc *fdp = p->p_fd;
 1496         struct file     *fp;
 1497         struct svr4_32_strbuf dat, ctl;
 1498         struct svr4_32_strmcmd sc;
 1499         struct sockaddr_in sain;
 1500         struct sockaddr_un saun;
 1501         void *skp, *sup;
 1502         int sasize;
 1503         struct svr4_strm *st;
 1504         int error;
 1505         caddr_t sg;
 1506 
 1507 #ifdef DEBUG_SVR4
 1508         show_msg(">putmsg", SCARG(uap, fd), SCARG(uap, ctl),
 1509                  SCARG(uap, dat), SCARG(uap, flags));
 1510 #endif /* DEBUG_SVR4 */
 1511 
 1512         if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
 1513                 return EBADF;
 1514 
 1515         if (SCARG(uap, ctl)) {
 1516                 if ((error = copyin((caddr_t)(u_long)SCARG(uap, ctl), 
 1517                                     &ctl, sizeof(ctl))) != 0)
 1518                         return error;
 1519         }
 1520         else
 1521                 ctl.len = -1;
 1522 
 1523         if (SCARG(uap, dat)) {
 1524                 if ((error = copyin((caddr_t)(u_long)SCARG(uap, dat), 
 1525                                     &dat, sizeof(dat))) != 0)
 1526                         return error;
 1527         }
 1528         else
 1529                 dat.len = -1;
 1530 
 1531         /*
 1532          * Only for sockets for now.
 1533          */
 1534         if ((st = svr4_32_stream_get(fp)) == NULL) {
 1535                 DPRINTF(("putmsg: bad file type\n"));
 1536                 return EINVAL;
 1537         }
 1538 
 1539         if (ctl.len > sizeof(sc)) {
 1540                 DPRINTF(("putmsg: Bad control size %ld != %d\n",
 1541                     (unsigned long)sizeof(struct svr4_32_strmcmd), ctl.len));
 1542                 return EINVAL;
 1543         }
 1544 
 1545         if ((error = copyin((caddr_t)(u_long)ctl.buf, &sc, ctl.len)) != 0)
 1546                 return error;
 1547 
 1548         switch (st->s_family) {
 1549         case AF_INET:
 1550                 if (sc.len != sizeof(sain)) {
 1551 #ifdef notyet
 1552                         if (sc.cmd == SVR4_TI_DATA_REQUEST) {
 1553                                 struct sys_write_args wa;
 1554 
 1555                                 /* Solaris seems to use sc.cmd = 3 to
 1556                                  * send "expedited" data.  telnet uses
 1557                                  * this for options processing, sending EOF,
 1558                                  * etc.  I'm sure other things use it too.
 1559                                  * I don't have any documentation
 1560                                  * on it, so I'm making a guess that this
 1561                                  * is how it works. newton@atdot.dotat.org XXX
 1562                                  *
 1563                                  * Hmm, expedited data seems to be sc.cmd = 4.
 1564                                  * I think 3 is normal data. (christos)
 1565                                  */
 1566                                 DPRINTF(("sending expedited data (?)\n"));
 1567                                 SCARG(&wa, fd) = SCARG(uap, fd);
 1568                                 SCARG(&wa, buf) = dat.buf;
 1569                                 SCARG(&wa, nbyte) = dat.len;
 1570                                 return sys_write(p, &wa, retval);
 1571                         }
 1572 #endif
 1573                         DPRINTF(("putmsg: Invalid inet length %ld\n", sc.len));
 1574                         return EINVAL;
 1575                 }
 1576                 netaddr_to_sockaddr_in(&sain, &sc);
 1577                 skp = &sain;
 1578                 sasize = sizeof(sain);
 1579                 error = sain.sin_family != st->s_family;
 1580                 break;
 1581 
 1582         case AF_LOCAL:
 1583                 if (ctl.len == 8) {
 1584                         /* We are doing an accept; succeed */
 1585                         DPRINTF(("putmsg: Do nothing\n"));
 1586                         *retval = 0;
 1587                         return 0;
 1588                 }
 1589                 else {
 1590                         /* Maybe we've been given a device/inode pair */
 1591                         dev_t *dev = SVR4_ADDROF(&sc);
 1592                         ino_t *ino = (ino_t *) &dev[1];
 1593                         skp = svr4_find_socket(p, fp, *dev, *ino);
 1594                         if (skp == NULL) {
 1595                                 skp = &saun;
 1596                                 /* I guess we have it by name */
 1597                                 netaddr_to_sockaddr_un(skp, &sc);
 1598                         }
 1599                         sasize = sizeof(saun);
 1600                 }
 1601                 break;
 1602 
 1603         default:
 1604                 DPRINTF(("putmsg: Unsupported address family %d\n",
 1605                          st->s_family));
 1606                 return ENOSYS;
 1607         }
 1608 
 1609         sg = stackgap_init(p, 0);
 1610         sup = stackgap_alloc(p, &sg, sasize);
 1611 
 1612         if ((error = copyout(skp, sup, sasize)) != 0)
 1613                 return error;
 1614 
 1615         switch (st->s_cmd = sc.cmd) {
 1616         case SVR4_TI_CONNECT_REQUEST:   /* connect      */
 1617                 {
 1618                         struct sys_connect_args co;
 1619 
 1620                         SCARG(&co, s) = SCARG(uap, fd);
 1621                         SCARG(&co, name) = (void *) sup;
 1622                         SCARG(&co, namelen) = (int) sasize;
 1623                         return sys_connect(l, &co, retval);
 1624                 }
 1625 
 1626         case SVR4_TI_SENDTO_REQUEST:    /* sendto       */
 1627                 {
 1628                         struct msghdr msg;
 1629                         struct iovec aiov;
 1630 
 1631                         msg.msg_name = (caddr_t) sup;
 1632                         msg.msg_namelen = sasize;
 1633                         msg.msg_iov = &aiov;
 1634                         msg.msg_iovlen = 1;
 1635                         msg.msg_control = 0;
 1636                         msg.msg_flags = 0;
 1637                         aiov.iov_base = (caddr_t)(u_long)dat.buf;
 1638                         aiov.iov_len = dat.len;
 1639                         error = sendit(p, SCARG(uap, fd), &msg,
 1640                                        SCARG(uap, flags), retval);
 1641 
 1642                         *retval = 0;
 1643                         return error;
 1644                 }
 1645 
 1646         default:
 1647                 DPRINTF(("putmsg: Unimplemented command %lx\n", sc.cmd));
 1648                 return ENOSYS;
 1649         }
 1650 }
 1651 
 1652 
 1653 int
 1654 svr4_32_sys_getmsg(l, v, retval)
 1655         struct lwp *l;
 1656         void *v;
 1657         register_t *retval;
 1658 {
 1659         struct svr4_32_sys_getmsg_args *uap = v;
 1660         struct proc *p = l->l_proc;
 1661         struct filedesc *fdp = p->p_fd;
 1662         struct file     *fp;
 1663         struct sys_getpeername_args ga;
 1664         struct sys_accept_args aa;
 1665         struct svr4_32_strbuf dat, ctl;
 1666         struct svr4_32_strmcmd sc;
 1667         int error;
 1668         struct msghdr msg;
 1669         struct iovec aiov;
 1670         struct sockaddr_in sain;
 1671         struct sockaddr_un saun;
 1672         void *skp, *sup;
 1673         int sasize;
 1674         struct svr4_strm *st;
 1675         int *flen;
 1676         int fl;
 1677         caddr_t sg;
 1678 
 1679         memset(&sc, 0, sizeof(sc));
 1680 
 1681 #ifdef DEBUG_SVR4
 1682         show_msg(">getmsg", SCARG(uap, fd), SCARG(uap, ctl),
 1683                  SCARG(uap, dat), 0);
 1684 #endif /* DEBUG_SVR4 */
 1685 
 1686         if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
 1687                 return EBADF;
 1688 
 1689         if (SCARG(uap, ctl)) {
 1690                 if ((error = copyin((caddr_t)(u_long)SCARG(uap, ctl), 
 1691                                     &ctl, sizeof(ctl))) != 0)
 1692                         return error;
 1693         }
 1694         else {
 1695                 ctl.len = -1;
 1696                 ctl.maxlen = 0;
 1697         }
 1698 
 1699         if (SCARG(uap, dat)) {
 1700                 if ((error = copyin((caddr_t)(u_long)SCARG(uap, dat), 
 1701                                     &dat, sizeof(dat))) != 0)
 1702                         return error;
 1703         }
 1704         else {
 1705                 dat.len = -1;
 1706                 dat.maxlen = 0;
 1707         }
 1708 
 1709         /*
 1710          * Only for sockets for now.
 1711          */
 1712         if ((st = svr4_32_stream_get(fp)) == NULL) {
 1713                 DPRINTF(("getmsg: bad file type\n"));
 1714                 return EINVAL;
 1715         }
 1716 
 1717         if (ctl.maxlen == -1 || dat.maxlen == -1) {
 1718                 DPRINTF(("getmsg: Cannot handle -1 maxlen (yet)\n"));
 1719                 return ENOSYS;
 1720         }
 1721 
 1722         switch (st->s_family) {
 1723         case AF_INET:
 1724                 skp = &sain;
 1725                 sasize = sizeof(sain);
 1726                 break;
 1727 
 1728         case AF_LOCAL:
 1729                 skp = &saun;
 1730                 sasize = sizeof(saun);
 1731                 break;
 1732 
 1733         default:
 1734                 DPRINTF(("getmsg: Unsupported address family %d\n",
 1735                          st->s_family));
 1736                 return ENOSYS;
 1737         }
 1738 
 1739         sg = stackgap_init(p, 0);
 1740         sup = stackgap_alloc(p, &sg, sasize);
 1741         flen = (int *) stackgap_alloc(p, &sg, sizeof(*flen));
 1742 
 1743         fl = sasize;
 1744         if ((error = copyout(&fl, flen, sizeof(fl))) != 0)
 1745                 return error;
 1746 
 1747         switch (st->s_cmd) {
 1748         case SVR4_TI_CONNECT_REQUEST:
 1749                 DPRINTF(("getmsg: TI_CONNECT_REQUEST\n"));
 1750                 /*
 1751                  * We do the connect in one step, so the putmsg should
 1752                  * have gotten the error.
 1753                  */
 1754                 sc.cmd = SVR4_TI_OK_REPLY;
 1755                 sc.len = 0;
 1756 
 1757                 ctl.len = 8;
 1758                 dat.len = -1;
 1759                 fl = 1;
 1760                 st->s_cmd = sc.cmd;
 1761                 break;
 1762 
 1763         case SVR4_TI_OK_REPLY:
 1764                 DPRINTF(("getmsg: TI_OK_REPLY\n"));
 1765                 /*
 1766                  * We are immediately after a connect reply, so we send
 1767                  * a connect verification.
 1768                  */
 1769 
 1770                 SCARG(&ga, fdes) = SCARG(uap, fd);
 1771                 SCARG(&ga, asa) = (void *) sup;
 1772                 SCARG(&ga, alen) = flen;
 1773                 
 1774                 if ((error = sys_getpeername(l, &ga, retval)) != 0) {
 1775                         DPRINTF(("getmsg: getpeername failed %d\n", error));
 1776                         return error;
 1777                 }
 1778 
 1779                 if ((error = copyin(sup, skp, sasize)) != 0)
 1780                         return error;
 1781                 
 1782                 sc.cmd = SVR4_TI_CONNECT_REPLY;
 1783                 sc.pad[0] = 0x4;
 1784                 sc.offs = 0x18;
 1785                 sc.pad[1] = 0x14;
 1786                 sc.pad[2] = 0x04000402;
 1787 
 1788                 switch (st->s_family) {
 1789                 case AF_INET:
 1790                         sc.len = sasize;
 1791                         sockaddr_to_netaddr_in(&sc, &sain);
 1792                         break;
 1793 
 1794                 case AF_LOCAL:
 1795                         sc.len = sasize + 4;
 1796                         sockaddr_to_netaddr_un(&sc, &saun);
 1797                         break;
 1798 
 1799                 default:
 1800                         return ENOSYS;
 1801                 }
 1802 
 1803                 ctl.len = 40;
 1804                 dat.len = -1;
 1805                 fl = 0;
 1806                 st->s_cmd = sc.cmd;
 1807                 break;
 1808 
 1809         case SVR4_TI__ACCEPT_OK:
 1810                 DPRINTF(("getmsg: TI__ACCEPT_OK\n"));
 1811                 /*
 1812                  * We do the connect in one step, so the putmsg should
 1813                  * have gotten the error.
 1814                  */
 1815                 sc.cmd = SVR4_TI_OK_REPLY;
 1816                 sc.len = 1;
 1817 
 1818                 ctl.len = 8;
 1819                 dat.len = -1;
 1820                 fl = 1;
 1821                 st->s_cmd = SVR4_TI__ACCEPT_WAIT;
 1822                 break;
 1823 
 1824         case SVR4_TI__ACCEPT_WAIT:
 1825                 DPRINTF(("getmsg: TI__ACCEPT_WAIT\n"));
 1826                 /*
 1827                  * We are after a listen, so we try to accept...
 1828                  */
 1829                 SCARG(&aa, s) = SCARG(uap, fd);
 1830                 SCARG(&aa, name) = (void *) sup;
 1831                 SCARG(&aa, anamelen) = flen;
 1832                 
 1833                 if ((error = sys_accept(l, &aa, retval)) != 0) {
 1834                         DPRINTF(("getmsg: accept failed %d\n", error));
 1835                         return error;
 1836                 }
 1837 
 1838                 st->s_afd = *retval;
 1839 
 1840                 DPRINTF(("getmsg: Accept fd = %d\n", st->s_afd));
 1841 
 1842                 if ((error = copyin(sup, skp, sasize)) != 0)
 1843                         return error;
 1844                 
 1845                 sc.cmd = SVR4_TI_ACCEPT_REPLY;
 1846                 sc.offs = 0x18;
 1847                 sc.pad[0] = 0x0;
 1848 
 1849                 switch (st->s_family) {
 1850                 case AF_INET:
 1851                         sc.pad[1] = 0x28;
 1852                         sockaddr_to_netaddr_in(&sc, &sain);
 1853                         ctl.len = 40;
 1854                         sc.len = sasize;
 1855                         break;
 1856 
 1857                 case AF_LOCAL:
 1858                         sc.pad[1] = 0x00010000;
 1859                         sc.pad[2] = 0xf6bcdaa0; /* I don't know what that is */
 1860                         sc.pad[3] = 0x00010000;
 1861                         ctl.len = 134;
 1862                         sc.len = sasize + 4;
 1863                         break;
 1864 
 1865                 default:
 1866                         return ENOSYS;
 1867                 }
 1868 
 1869                 dat.len = -1;
 1870                 fl = 0;
 1871                 st->s_cmd = SVR4_TI__ACCEPT_OK;
 1872                 break;
 1873 
 1874         case SVR4_TI_SENDTO_REQUEST:
 1875                 DPRINTF(("getmsg: TI_SENDTO_REQUEST\n"));
 1876                 if (ctl.maxlen > 36 && ctl.len < 36)
 1877                     ctl.len = 36;
 1878                 if (ctl.len > sizeof(sc))
 1879                         ctl.len = sizeof(sc);
 1880 
 1881                 if ((error = copyin((caddr_t)(u_long)ctl.buf, &sc, ctl.len)) != 0)
 1882                         return error;
 1883 
 1884                 switch (st->s_family) {
 1885                 case AF_INET:
 1886                         sockaddr_to_netaddr_in(&sc, &sain);
 1887                         break;
 1888 
 1889                 case AF_LOCAL:
 1890                         sockaddr_to_netaddr_un(&sc, &saun);
 1891                         break;
 1892 
 1893                 default:
 1894                         return ENOSYS;
 1895                 }
 1896 
 1897                 msg.msg_name = (caddr_t) sup;
 1898                 msg.msg_namelen = sasize;
 1899                 msg.msg_iov = &aiov;
 1900                 msg.msg_iovlen = 1;
 1901                 msg.msg_control = 0;
 1902                 aiov.iov_base = (caddr_t)(u_long)dat.buf;
 1903                 aiov.iov_len = dat.maxlen;
 1904                 msg.msg_flags = 0;
 1905 
 1906                 error = recvit(p, SCARG(uap, fd), &msg, (caddr_t) flen,
 1907                     retval);
 1908 
 1909                 if (error) {
 1910                         DPRINTF(("getmsg: recvit failed %d\n", error));
 1911                         return error;
 1912                 }
 1913 
 1914                 if ((error = copyin(msg.msg_name, skp, sasize)) != 0)
 1915                         return error;
 1916 
 1917                 sc.cmd = SVR4_TI_RECVFROM_IND;
 1918 
 1919                 switch (st->s_family) {
 1920                 case AF_INET:
 1921                         sc.len = sasize;
 1922                         sockaddr_to_netaddr_in(&sc, &sain);
 1923                         break;
 1924 
 1925                 case AF_LOCAL:
 1926                         sc.len = sasize + 4;
 1927                         sockaddr_to_netaddr_un(&sc, &saun);
 1928                         break;
 1929 
 1930                 default:
 1931                         return ENOSYS;
 1932                 }
 1933 
 1934                 dat.len = *retval;
 1935                 fl = 0;
 1936                 st->s_cmd = sc.cmd;
 1937                 break;
 1938 
 1939         default:
 1940                 st->s_cmd = sc.cmd;
 1941 #ifdef notyet
 1942                 if (st->s_cmd == SVR4_TI_CONNECT_REQUEST) {
 1943                         struct sys_read_args ra;
 1944 
 1945                         /* More weirdness:  Again, I can't find documentation
 1946                          * to back this up, but when a process does a generic
 1947                          * "getmsg()" call it seems that the command field is
 1948                          * zero and the length of the data area is zero.  I
 1949                          * think processes expect getmsg() to fill in dat.len
 1950                          * after reading at most dat.maxlen octets from the
 1951                          * stream.  Since we're using sockets I can let 
 1952                          * read() look after it and frob return values
 1953                          * appropriately (or inappropriately :-)
 1954                          *   -- newton@atdot.dotat.org        XXX
 1955                          */
 1956                         SCARG(&ra, fd) = SCARG(uap, fd);
 1957                         SCARG(&ra, buf) = dat.buf;
 1958                         SCARG(&ra, nbyte) = dat.maxlen;
 1959                         if ((error = sys_read(p, &ra, retval)) != 0)
 1960                                 return error;
 1961                         dat.len = *retval;
 1962                         *retval = 0;
 1963                         st->s_cmd = SVR4_TI_SENDTO_REQUEST;
 1964                         break;
 1965                         
 1966                 }
 1967 #endif
 1968                 DPRINTF(("getmsg: Unknown state %x\n", st->s_cmd));
 1969                 return EINVAL;
 1970         }
 1971 
 1972         if (SCARG(uap, ctl)) {
 1973                 if (ctl.len != -1)
 1974                         if ((error = copyout(&sc, (caddr_t)(u_long)ctl.buf, 
 1975                                              ctl.len)) != 0)
 1976                                 return error;
 1977 
 1978                 if ((error = copyout(&ctl, (caddr_t)(u_long)SCARG(uap, ctl), 
 1979                                      sizeof(ctl))) != 0)
 1980                         return error;
 1981         }
 1982 
 1983         if (SCARG(uap, dat)) {
 1984                 if ((error = copyout(&dat, (caddr_t)(u_long)SCARG(uap, dat), 
 1985                                      sizeof(dat))) != 0)
 1986                         return error;
 1987         }
 1988 
 1989         if (SCARG(uap, flags)) { /* XXX: Need translation */
 1990                 if ((error = copyout(&fl, (caddr_t)(u_long)SCARG(uap, flags), 
 1991                                      sizeof(fl))) != 0)
 1992                         return error;
 1993         }
 1994 
 1995         *retval = 0;
 1996 
 1997 #ifdef DEBUG_SVR4
 1998         show_msg("<getmsg", SCARG(uap, fd), SCARG(uap, ctl),
 1999                  SCARG(uap, dat), fl);
 2000 #endif /* DEBUG_SVR4 */
 2001         return error;
 2002 }

Cache object: 7aa6fbe67b76fe23563125e8dda2fed4


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