1 /* $NetBSD: ninepuffs.c,v 1.22 2007/11/16 18:39:01 pooka Exp $ */
4 * Copyright (c) 2007 Antti Kantee. All Rights Reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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
29 * 9puffs: access a 9P file server as a vfs via puffs
32 #include <sys/cdefs.h>
34 __RCSID("$NetBSD: ninepuffs.c,v 1.22 2007/11/16 18:39:01 pooka Exp $");
37 #include <sys/types.h>
38 #include <sys/socket.h>
41 #include <netinet/in.h>
52 #include "ninepuffs.h"
54 #define DEFPORT_9P 564
60 fprintf(stderr
, "usage: %s [-s] [-o mntopts] [-p port] "
61 "[user@]server[:path] mountpoint\n", getprogname());
66 * TCPv4 connection to 9P file server, forget IL and IPv6 for now.
67 * Return connected socket or exit with error.
70 serverconnect(const char *addr
, unsigned short port
)
72 struct sockaddr_in mysin
;
76 he
= gethostbyname2(addr
, AF_INET
);
78 herror("gethostbyname");
82 s
= socket(PF_INET
, SOCK_STREAM
, IPPROTO_TCP
);
86 memset(&mysin
, 0, sizeof(struct sockaddr_in
));
87 mysin
.sin_family
= AF_INET
;
88 mysin
.sin_port
= htons(port
);
89 memcpy(&mysin
.sin_addr
, he
->h_addr
, sizeof(struct in_addr
));
91 if (connect(s
, (struct sockaddr
*)&mysin
, sizeof(mysin
)) == -1)
98 main(int argc
, char *argv
[])
101 struct puffs_usermount
*pu
;
102 struct puffs_ops
*pops
;
103 struct puffs_node
*pn_root
;
105 const char *user
, *srvhost
, *srvpath
;
108 int mntflags
, pflags
, ch
;
111 setprogname(argv
[0]);
116 mntflags
= pflags
= 0;
120 while ((ch
= getopt(argc
, argv
, "o:p:s")) != -1) {
123 mp
= getmntopts(optarg
, puffsmopts
, &mntflags
, &pflags
);
125 err(1, "getmntopts");
145 if (pflags
& PUFFS_FLAG_OPDUMP
)
147 pflags
|= PUFFS_KFLAG_WTCACHE
| PUFFS_KFLAG_IAONDEMAND
;
151 PUFFSOP_SET(pops
, puffs9p
, fs
, unmount
);
152 PUFFSOP_SETFSNOP(pops
, sync
);
153 PUFFSOP_SETFSNOP(pops
, statvfs
);
155 PUFFSOP_SET(pops
, puffs9p
, node
, lookup
);
156 PUFFSOP_SET(pops
, puffs9p
, node
, readdir
);
157 PUFFSOP_SET(pops
, puffs9p
, node
, getattr
);
158 PUFFSOP_SET(pops
, puffs9p
, node
, setattr
);
159 PUFFSOP_SET(pops
, puffs9p
, node
, create
);
160 PUFFSOP_SET(pops
, puffs9p
, node
, open
);
161 PUFFSOP_SET(pops
, puffs9p
, node
, mkdir
);
162 PUFFSOP_SET(pops
, puffs9p
, node
, remove
);
163 PUFFSOP_SET(pops
, puffs9p
, node
, rmdir
);
164 PUFFSOP_SET(pops
, puffs9p
, node
, read
);
165 PUFFSOP_SET(pops
, puffs9p
, node
, write
);
166 PUFFSOP_SET(pops
, puffs9p
, node
, rename
);
167 PUFFSOP_SET(pops
, puffs9p
, node
, inactive
);
168 PUFFSOP_SET(pops
, puffs9p
, node
, reclaim
);
170 PUFFSOP_SET(pops
, puffs9p
, node
, mknod
);
173 pu
= puffs_init(pops
, argv
[0], "9p", &p9p
, pflags
);
175 err(1, "puffs_init");
177 memset(&p9p
, 0, sizeof(p9p
));
178 p9p
.maxreq
= P9P_DEFREQLEN
;
182 if ((p
= strchr(argv
[0], '@')) != NULL
) {
190 pw
= getpwuid(getuid());
197 if ((p
= strchr(srvhost
, ':')) != NULL
) {
201 errx(1, "%s is not an absolute path", srvpath
);
206 p9p
.servsock
= serverconnect(srvhost
, port
);
207 if ((pn_root
= p9p_handshake(pu
, user
, srvpath
)) == NULL
) {
212 puffs_framev_init(pu
, p9pbuf_read
, p9pbuf_write
, p9pbuf_cmp
, NULL
,
213 puffs_framev_unmountonclose
);
214 if (puffs_framev_addfd(pu
, p9p
.servsock
,
215 PUFFS_FBIO_READ
| PUFFS_FBIO_WRITE
) == -1)
216 err(1, "puffs_framebuf_addfd");
219 if (puffs_daemon(pu
, 1, 1) == -1)
220 err(1, "puffs_daemon");
222 if (puffs_mount(pu
, argv
[1], mntflags
, pn_root
) == -1)
223 err(1, "puffs_mount");
224 if (puffs_setblockingmode(pu
, PUFFSDEV_NONBLOCK
) == -1)
225 err(1, "setblockingmode");
227 if (puffs_mainloop(pu
) == -1)