[BACK]Return to svr4_stream.c CVS log [TXT][DIR] Up to [local] / sys / compat / svr4

Annotation of sys/compat/svr4/svr4_stream.c, Revision 1.1.1.1

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

CVSweb