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


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

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

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

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

Cache object: 7a32222adc9ed408bbac898a8915969d


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