[BACK]Return to ninepuffs.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / usr.sbin / puffs / mount_9p

Annotation of src/usr.sbin/puffs/mount_9p/ninepuffs.c, Revision 1.29

1.29    ! uwe         1: /*     $NetBSD: ninepuffs.c,v 1.28 2020/05/29 23:49:08 uwe Exp $       */
1.1       pooka       2:
                      3: /*
                      4:  * Copyright (c) 2007  Antti Kantee.  All Rights Reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  * 2. Redistributions in binary form must reproduce the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer in the
                     13:  *    documentation and/or other materials provided with the distribution.
                     14:  *
                     15:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
                     16:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
                     18:  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     19:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     20:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
                     21:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     22:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     23:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     24:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     25:  * SUCH DAMAGE.
                     26:  */
                     27:
                     28: /*
                     29:  * 9puffs: access a 9P file server as a vfs via puffs
                     30:  */
                     31:
                     32: #include <sys/cdefs.h>
                     33: #ifndef lint
1.29    ! uwe        34: __RCSID("$NetBSD: ninepuffs.c,v 1.28 2020/05/29 23:49:08 uwe Exp $");
1.1       pooka      35: #endif /* !lint */
                     36:
                     37: #include <sys/types.h>
                     38: #include <sys/socket.h>
                     39: #include <sys/poll.h>
                     40:
                     41: #include <netinet/in.h>
                     42:
                     43: #include <assert.h>
                     44: #include <err.h>
                     45: #include <netdb.h>
1.15      pooka      46: #include <pwd.h>
1.1       pooka      47: #include <puffs.h>
                     48: #include <stdio.h>
                     49: #include <stdlib.h>
                     50: #include <unistd.h>
                     51:
                     52: #include "ninepuffs.h"
1.25      ozaki-r    53: #include "nineproto.h"
1.1       pooka      54:
                     55: #define DEFPORT_9P 564
                     56:
1.24      joerg      57: __dead static void
1.1       pooka      58: usage(void)
                     59: {
                     60:
1.26      ozaki-r    61:        fprintf(stderr, "usage: %s [-su] [-o mntopts] [-p port] "
1.18      pooka      62:            "[user@]server[:path] mountpoint\n", getprogname());
1.27      ozaki-r    63:        fprintf(stderr, "       %s -c [-su] [-o mntopts] devfile mountpoint\n",
                     64:            getprogname());
1.18      pooka      65:        exit(1);
1.1       pooka      66: }
                     67:
                     68: /*
                     69:  * TCPv4 connection to 9P file server, forget IL and IPv6 for now.
                     70:  * Return connected socket or exit with error.
                     71:  */
                     72: static int
                     73: serverconnect(const char *addr, unsigned short port)
                     74: {
                     75:        struct sockaddr_in mysin;
                     76:        struct hostent *he;
1.27      ozaki-r    77:        int s, ret, opt;
1.1       pooka      78:
                     79:        he = gethostbyname2(addr, AF_INET);
                     80:        if (he == NULL) {
                     81:                herror("gethostbyname");
                     82:                exit(1);
                     83:        }
                     84:
                     85:        s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
                     86:        if (s == -1)
                     87:                err(1, "socket");
                     88:
1.27      ozaki-r    89:        opt = 1;
                     90:        ret = setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
                     91:        if (ret == -1)
                     92:                err(1, "setsockopt(SO_NOSIGPIPE)");
                     93:
1.1       pooka      94:        memset(&mysin, 0, sizeof(struct sockaddr_in));
                     95:        mysin.sin_family = AF_INET;
                     96:        mysin.sin_port = htons(port);
                     97:        memcpy(&mysin.sin_addr, he->h_addr, sizeof(struct in_addr));
                     98:
                     99:        if (connect(s, (struct sockaddr *)&mysin, sizeof(mysin)) == -1)
                    100:                err(1, "connect");
                    101:
                    102:        return s;
                    103: }
                    104:
1.27      ozaki-r   105: static int
                    106: open_cdev(const char *path)
                    107: {
                    108:        int s;
                    109:
                    110:        s = open(path, O_RDWR, 0);
                    111:        if (s == -1)
                    112:                err(1, "%s", path);
                    113:        return s;
                    114: }
                    115:
1.1       pooka     116: int
                    117: main(int argc, char *argv[])
                    118: {
                    119:        struct puffs9p p9p;
                    120:        struct puffs_usermount *pu;
                    121:        struct puffs_ops *pops;
                    122:        struct puffs_node *pn_root;
                    123:        mntoptparse_t mp;
1.15      pooka     124:        const char *user, *srvhost, *srvpath;
                    125:        char *p;
1.1       pooka     126:        unsigned short port;
1.19      pooka     127:        int mntflags, pflags, ch;
1.1       pooka     128:        int detach;
1.27      ozaki-r   129:        int protover;
                    130:        int server;
1.1       pooka     131:
                    132:        setprogname(argv[0]);
                    133:
1.14      pooka     134:        if (argc < 2)
1.1       pooka     135:                usage();
                    136:
1.19      pooka     137:        mntflags = pflags = 0;
1.1       pooka     138:        detach = 1;
                    139:        port = DEFPORT_9P;
1.27      ozaki-r   140:        protover = P9PROTO_VERSION;
                    141:        server = P9P_SERVER_TCP;
1.1       pooka     142:
1.27      ozaki-r   143:        while ((ch = getopt(argc, argv, "co:p:su")) != -1) {
1.1       pooka     144:                switch (ch) {
1.27      ozaki-r   145:                case 'c':
                    146:                        server = P9P_SERVER_CDEV;
                    147:                        break;
1.1       pooka     148:                case 'o':
                    149:                        mp = getmntopts(optarg, puffsmopts, &mntflags, &pflags);
                    150:                        if (mp == NULL)
                    151:                                err(1, "getmntopts");
                    152:                        freemntopts(mp);
                    153:                        break;
                    154:                case 'p':
                    155:                        port = atoi(optarg);
                    156:                        break;
                    157:                case 's':
1.19      pooka     158:                        detach = 0;
1.1       pooka     159:                        break;
1.25      ozaki-r   160:                case 'u':
                    161:                        protover = P9PROTO_VERSION_U;
                    162:                        break;
1.1       pooka     163:                default:
                    164:                        usage();
                    165:                        /*NOTREACHED*/
                    166:                }
                    167:        }
                    168:        argc -= optind;
                    169:        argv += optind;
                    170:
1.14      pooka     171:        if (argc != 2)
1.1       pooka     172:                usage();
                    173:
                    174:        if (pflags & PUFFS_FLAG_OPDUMP)
1.19      pooka     175:                detach = 0;
1.7       pooka     176:        pflags |= PUFFS_KFLAG_WTCACHE | PUFFS_KFLAG_IAONDEMAND;
1.1       pooka     177:
                    178:        PUFFSOP_INIT(pops);
                    179:
                    180:        PUFFSOP_SET(pops, puffs9p, fs, unmount);
                    181:        PUFFSOP_SETFSNOP(pops, sync);
                    182:        PUFFSOP_SETFSNOP(pops, statvfs);
                    183:
                    184:        PUFFSOP_SET(pops, puffs9p, node, lookup);
                    185:        PUFFSOP_SET(pops, puffs9p, node, readdir);
                    186:        PUFFSOP_SET(pops, puffs9p, node, getattr);
                    187:        PUFFSOP_SET(pops, puffs9p, node, setattr);
                    188:        PUFFSOP_SET(pops, puffs9p, node, create);
                    189:        PUFFSOP_SET(pops, puffs9p, node, open);
                    190:        PUFFSOP_SET(pops, puffs9p, node, mkdir);
                    191:        PUFFSOP_SET(pops, puffs9p, node, remove);
                    192:        PUFFSOP_SET(pops, puffs9p, node, rmdir);
                    193:        PUFFSOP_SET(pops, puffs9p, node, read);
                    194:        PUFFSOP_SET(pops, puffs9p, node, write);
                    195:        PUFFSOP_SET(pops, puffs9p, node, rename);
1.6       pooka     196:        PUFFSOP_SET(pops, puffs9p, node, inactive);
1.12      pooka     197:        PUFFSOP_SET(pops, puffs9p, node, reclaim);
1.1       pooka     198: #if 0
                    199:        PUFFSOP_SET(pops, puffs9p, node, mknod);
                    200: #endif
                    201:
1.16      pooka     202:        pu = puffs_init(pops, argv[0], "9p", &p9p, pflags);
1.15      pooka     203:        if (pu == NULL)
                    204:                err(1, "puffs_init");
                    205:
1.1       pooka     206:        memset(&p9p, 0, sizeof(p9p));
                    207:        p9p.maxreq = P9P_DEFREQLEN;
                    208:        p9p.nextfid = 1;
1.25      ozaki-r   209:        p9p.protover = protover;
1.29    ! uwe       210:        p9p.server = server;
1.1       pooka     211:
1.15      pooka     212:        /* user@ */
                    213:        if ((p = strchr(argv[0], '@')) != NULL) {
                    214:                *p = '\0';
                    215:                srvhost = p+1;
                    216:                user = argv[0];
                    217:        } else {
                    218:                struct passwd *pw;
                    219:
                    220:                srvhost = argv[0];
                    221:                pw = getpwuid(getuid());
                    222:                if (pw == NULL)
                    223:                        err(1, "getpwuid");
                    224:                user = pw->pw_name;
                    225:        }
                    226:
                    227:        /* :/mountpath */
                    228:        if ((p = strchr(srvhost, ':')) != NULL) {
                    229:                *p = '\0';
                    230:                srvpath = p+1;
                    231:                if (*srvpath != '/')
                    232:                        errx(1, "%s is not an absolute path", srvpath);
                    233:        } else {
                    234:                srvpath = "/";
                    235:        }
                    236:
1.29    ! uwe       237:        if (p9p.server == P9P_SERVER_TCP) {
1.27      ozaki-r   238:                p9p.servsock = serverconnect(srvhost, port);
                    239:        } else {
1.28      uwe       240:                /* path to a vio9p(4) device, e.g., /dev/vio9p0 */
1.27      ozaki-r   241:                p9p.servsock = open_cdev(argv[0]);
                    242:        }
                    243:
1.15      pooka     244:        if ((pn_root = p9p_handshake(pu, user, srvpath)) == NULL) {
1.27      ozaki-r   245:                close(p9p.servsock);
1.1       pooka     246:                puffs_exit(pu, 1);
                    247:                exit(1);
                    248:        }
                    249:
1.17      pooka     250:        puffs_framev_init(pu, p9pbuf_read, p9pbuf_write, p9pbuf_cmp, NULL,
1.10      pooka     251:            puffs_framev_unmountonclose);
1.13      pooka     252:        if (puffs_framev_addfd(pu, p9p.servsock,
                    253:            PUFFS_FBIO_READ | PUFFS_FBIO_WRITE) == -1)
1.9       pooka     254:                err(1, "puffs_framebuf_addfd");
1.1       pooka     255:
1.19      pooka     256:        if (detach)
1.22      pooka     257:                if (puffs_daemon(pu, 1, 1) == -1)
                    258:                        err(1, "puffs_daemon");
1.19      pooka     259:
1.20      pooka     260:        if (puffs_mount(pu, argv[1], mntflags, pn_root) == -1)
                    261:                err(1, "puffs_mount");
1.21      pooka     262:        if (puffs_setblockingmode(pu, PUFFSDEV_NONBLOCK) == -1)
                    263:                err(1, "setblockingmode");
                    264:
1.19      pooka     265:        if (puffs_mainloop(pu) == -1)
1.20      pooka     266:                err(1, "mainloop");
1.27      ozaki-r   267:        close(p9p.servsock);
                    268:        puffs_exit(pu, 1);
1.19      pooka     269:
                    270:        return 0;
1.1       pooka     271: }

CVSweb <webmaster@jp.NetBSD.org>