15812c3ccSTomohiro Kusumi /*-
25812c3ccSTomohiro Kusumi * Copyright (c) 2019 Tomohiro Kusumi <tkusumi@netbsd.org>
35812c3ccSTomohiro Kusumi * Copyright (c) 2019 The DragonFly Project
45812c3ccSTomohiro Kusumi * All rights reserved.
55812c3ccSTomohiro Kusumi *
65812c3ccSTomohiro Kusumi * Redistribution and use in source and binary forms, with or without
75812c3ccSTomohiro Kusumi * modification, are permitted provided that the following conditions
85812c3ccSTomohiro Kusumi * are met:
95812c3ccSTomohiro Kusumi * 1. Redistributions of source code must retain the above copyright
105812c3ccSTomohiro Kusumi * notice, this list of conditions and the following disclaimer.
115812c3ccSTomohiro Kusumi * 2. Redistributions in binary form must reproduce the above copyright
125812c3ccSTomohiro Kusumi * notice, this list of conditions and the following disclaimer in the
135812c3ccSTomohiro Kusumi * documentation and/or other materials provided with the distribution.
145812c3ccSTomohiro Kusumi *
155812c3ccSTomohiro Kusumi * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
165812c3ccSTomohiro Kusumi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
175812c3ccSTomohiro Kusumi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
185812c3ccSTomohiro Kusumi * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
195812c3ccSTomohiro Kusumi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
205812c3ccSTomohiro Kusumi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
215812c3ccSTomohiro Kusumi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
225812c3ccSTomohiro Kusumi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
235812c3ccSTomohiro Kusumi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
245812c3ccSTomohiro Kusumi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
255812c3ccSTomohiro Kusumi * SUCH DAMAGE.
265812c3ccSTomohiro Kusumi */
275812c3ccSTomohiro Kusumi
285812c3ccSTomohiro Kusumi #include "fuse.h"
295812c3ccSTomohiro Kusumi
305812c3ccSTomohiro Kusumi void
fuse_hexdump(const char * p,size_t len)315812c3ccSTomohiro Kusumi fuse_hexdump(const char *p, size_t len)
325812c3ccSTomohiro Kusumi {
335812c3ccSTomohiro Kusumi int i;
345812c3ccSTomohiro Kusumi
355812c3ccSTomohiro Kusumi if (!fuse_debug)
365812c3ccSTomohiro Kusumi return;
375812c3ccSTomohiro Kusumi
385812c3ccSTomohiro Kusumi for (i = 0; i < (int)len; i++) {
395812c3ccSTomohiro Kusumi kprintf("%02X ", p[i] & 0xff);
405812c3ccSTomohiro Kusumi if ((i + 1) % 32 == 0)
415812c3ccSTomohiro Kusumi kprintf("\n");
425812c3ccSTomohiro Kusumi }
435812c3ccSTomohiro Kusumi kprintf("\n");
445812c3ccSTomohiro Kusumi }
455812c3ccSTomohiro Kusumi
465812c3ccSTomohiro Kusumi void
fuse_fill_in_header(struct fuse_in_header * ihd,uint32_t len,uint32_t opcode,uint64_t unique,uint64_t nodeid,uint32_t uid,uint32_t gid,uint32_t pid)475812c3ccSTomohiro Kusumi fuse_fill_in_header(struct fuse_in_header *ihd,
485812c3ccSTomohiro Kusumi uint32_t len, uint32_t opcode, uint64_t unique, uint64_t nodeid,
495812c3ccSTomohiro Kusumi uint32_t uid, uint32_t gid, uint32_t pid)
505812c3ccSTomohiro Kusumi {
515812c3ccSTomohiro Kusumi ihd->len = len;
525812c3ccSTomohiro Kusumi ihd->opcode = opcode;
535812c3ccSTomohiro Kusumi ihd->unique = unique;
545812c3ccSTomohiro Kusumi ihd->nodeid = nodeid;
555812c3ccSTomohiro Kusumi ihd->uid = uid;
565812c3ccSTomohiro Kusumi ihd->gid = gid;
575812c3ccSTomohiro Kusumi ihd->pid = pid;
585812c3ccSTomohiro Kusumi }
595812c3ccSTomohiro Kusumi
605812c3ccSTomohiro Kusumi int
fuse_forget_node(struct fuse_mount * fmp,uint64_t ino,uint64_t nlookup,struct ucred * cred)615812c3ccSTomohiro Kusumi fuse_forget_node(struct fuse_mount *fmp, uint64_t ino, uint64_t nlookup,
625812c3ccSTomohiro Kusumi struct ucred *cred)
635812c3ccSTomohiro Kusumi {
645812c3ccSTomohiro Kusumi struct fuse_ipc *fip;
655812c3ccSTomohiro Kusumi struct fuse_forget_in *ffi;
665812c3ccSTomohiro Kusumi int error;
675812c3ccSTomohiro Kusumi
685812c3ccSTomohiro Kusumi KKASSERT(nlookup > 0);
695812c3ccSTomohiro Kusumi
705812c3ccSTomohiro Kusumi fip = fuse_ipc_get(fmp, sizeof(*ffi));
715812c3ccSTomohiro Kusumi ffi = fuse_ipc_fill(fip, FUSE_FORGET, ino, cred);
725812c3ccSTomohiro Kusumi ffi->nlookup = nlookup;
735812c3ccSTomohiro Kusumi
74*1a8e5e4cSMatthew Dillon error = fuse_ipc_tx_noreply(fip);
755812c3ccSTomohiro Kusumi if (error)
765812c3ccSTomohiro Kusumi return error;
775812c3ccSTomohiro Kusumi fuse_ipc_put(fip);
785812c3ccSTomohiro Kusumi
795812c3ccSTomohiro Kusumi return 0;
805812c3ccSTomohiro Kusumi }
815812c3ccSTomohiro Kusumi
825812c3ccSTomohiro Kusumi /*
835812c3ccSTomohiro Kusumi * Ignore FUSE_COMPAT_XXX which seem to exist for backward compatibility
845812c3ccSTomohiro Kusumi * for ancient versions of FUSE protocol.
855812c3ccSTomohiro Kusumi */
865812c3ccSTomohiro Kusumi int
fuse_audit_length(struct fuse_in_header * ihd,struct fuse_out_header * ohd)875812c3ccSTomohiro Kusumi fuse_audit_length(struct fuse_in_header *ihd, struct fuse_out_header *ohd)
885812c3ccSTomohiro Kusumi {
895812c3ccSTomohiro Kusumi size_t len = ohd->len - sizeof(struct fuse_out_header);
905812c3ccSTomohiro Kusumi bool res;
915812c3ccSTomohiro Kusumi
925812c3ccSTomohiro Kusumi switch (ihd->opcode) {
935812c3ccSTomohiro Kusumi case FUSE_LOOKUP:
945812c3ccSTomohiro Kusumi res = (len == sizeof(struct fuse_entry_out));
955812c3ccSTomohiro Kusumi break;
965812c3ccSTomohiro Kusumi case FUSE_FORGET:
975812c3ccSTomohiro Kusumi res = true;
985812c3ccSTomohiro Kusumi break;
995812c3ccSTomohiro Kusumi case FUSE_GETATTR:
1005812c3ccSTomohiro Kusumi res = (len == sizeof(struct fuse_attr_out));
1015812c3ccSTomohiro Kusumi break;
1025812c3ccSTomohiro Kusumi case FUSE_SETATTR:
1035812c3ccSTomohiro Kusumi res = (len == sizeof(struct fuse_attr_out));
1045812c3ccSTomohiro Kusumi break;
1055812c3ccSTomohiro Kusumi case FUSE_READLINK:
1065812c3ccSTomohiro Kusumi res = (len <= PAGE_SIZE);
1075812c3ccSTomohiro Kusumi break;
1085812c3ccSTomohiro Kusumi case FUSE_SYMLINK:
1095812c3ccSTomohiro Kusumi res = (len == sizeof(struct fuse_entry_out));
1105812c3ccSTomohiro Kusumi break;
1115812c3ccSTomohiro Kusumi case FUSE_MKNOD:
1125812c3ccSTomohiro Kusumi res = (len == sizeof(struct fuse_entry_out));
1135812c3ccSTomohiro Kusumi break;
1145812c3ccSTomohiro Kusumi case FUSE_MKDIR:
1155812c3ccSTomohiro Kusumi res = (len == sizeof(struct fuse_entry_out));
1165812c3ccSTomohiro Kusumi break;
1175812c3ccSTomohiro Kusumi case FUSE_UNLINK:
1185812c3ccSTomohiro Kusumi res = (len == 0);
1195812c3ccSTomohiro Kusumi break;
1205812c3ccSTomohiro Kusumi case FUSE_RMDIR:
1215812c3ccSTomohiro Kusumi res = (len == 0);
1225812c3ccSTomohiro Kusumi break;
1235812c3ccSTomohiro Kusumi case FUSE_RENAME:
1245812c3ccSTomohiro Kusumi res = (len == 0);
1255812c3ccSTomohiro Kusumi break;
1265812c3ccSTomohiro Kusumi case FUSE_LINK:
1275812c3ccSTomohiro Kusumi res = (len == sizeof(struct fuse_entry_out));
1285812c3ccSTomohiro Kusumi break;
1295812c3ccSTomohiro Kusumi case FUSE_OPEN:
1305812c3ccSTomohiro Kusumi res = (len == sizeof(struct fuse_open_out));
1315812c3ccSTomohiro Kusumi break;
1325812c3ccSTomohiro Kusumi case FUSE_READ:
1335812c3ccSTomohiro Kusumi res = (len <= ((struct fuse_read_in*)(ihd + 1))->size);
1345812c3ccSTomohiro Kusumi break;
1355812c3ccSTomohiro Kusumi case FUSE_WRITE:
1365812c3ccSTomohiro Kusumi res = (len == sizeof(struct fuse_write_out));
1375812c3ccSTomohiro Kusumi break;
1385812c3ccSTomohiro Kusumi case FUSE_STATFS:
1395812c3ccSTomohiro Kusumi res = (len == sizeof(struct fuse_statfs_out));
1405812c3ccSTomohiro Kusumi break;
1415812c3ccSTomohiro Kusumi case FUSE_RELEASE:
1425812c3ccSTomohiro Kusumi res = (len == 0);
1435812c3ccSTomohiro Kusumi break;
1445812c3ccSTomohiro Kusumi case FUSE_FSYNC:
1455812c3ccSTomohiro Kusumi res = (len == 0);
1465812c3ccSTomohiro Kusumi break;
1475812c3ccSTomohiro Kusumi case FUSE_SETXATTR:
1485812c3ccSTomohiro Kusumi res = (len == 0);
1495812c3ccSTomohiro Kusumi break;
1505812c3ccSTomohiro Kusumi case FUSE_GETXATTR:
1515812c3ccSTomohiro Kusumi res = true;
1525812c3ccSTomohiro Kusumi break;
1535812c3ccSTomohiro Kusumi case FUSE_LISTXATTR:
1545812c3ccSTomohiro Kusumi res = true;
1555812c3ccSTomohiro Kusumi break;
1565812c3ccSTomohiro Kusumi case FUSE_REMOVEXATTR:
1575812c3ccSTomohiro Kusumi res = (len == 0);
1585812c3ccSTomohiro Kusumi break;
1595812c3ccSTomohiro Kusumi case FUSE_FLUSH:
1605812c3ccSTomohiro Kusumi res = (len == 0);
1615812c3ccSTomohiro Kusumi break;
1625812c3ccSTomohiro Kusumi case FUSE_INIT:
1635812c3ccSTomohiro Kusumi res = (len == sizeof(struct fuse_init_out));
1645812c3ccSTomohiro Kusumi break;
1655812c3ccSTomohiro Kusumi case FUSE_OPENDIR:
1665812c3ccSTomohiro Kusumi res = (len == sizeof(struct fuse_open_out));
1675812c3ccSTomohiro Kusumi break;
1685812c3ccSTomohiro Kusumi case FUSE_READDIR:
1695812c3ccSTomohiro Kusumi res = (len <= ((struct fuse_read_in*)(ihd + 1))->size);
1705812c3ccSTomohiro Kusumi break;
1715812c3ccSTomohiro Kusumi case FUSE_RELEASEDIR:
1725812c3ccSTomohiro Kusumi res = (len == 0);
1735812c3ccSTomohiro Kusumi break;
1745812c3ccSTomohiro Kusumi case FUSE_FSYNCDIR:
1755812c3ccSTomohiro Kusumi res = (len == 0);
1765812c3ccSTomohiro Kusumi break;
1775812c3ccSTomohiro Kusumi case FUSE_GETLK:
1785812c3ccSTomohiro Kusumi res = false;
1795812c3ccSTomohiro Kusumi break;
1805812c3ccSTomohiro Kusumi case FUSE_SETLK:
1815812c3ccSTomohiro Kusumi res = false;
1825812c3ccSTomohiro Kusumi break;
1835812c3ccSTomohiro Kusumi case FUSE_SETLKW:
1845812c3ccSTomohiro Kusumi res = false;
1855812c3ccSTomohiro Kusumi break;
1865812c3ccSTomohiro Kusumi case FUSE_ACCESS:
1875812c3ccSTomohiro Kusumi res = (len == 0);
1885812c3ccSTomohiro Kusumi break;
1895812c3ccSTomohiro Kusumi case FUSE_CREATE:
1905812c3ccSTomohiro Kusumi res = (len == sizeof(struct fuse_entry_out) +
1915812c3ccSTomohiro Kusumi sizeof(struct fuse_open_out));
1925812c3ccSTomohiro Kusumi break;
1935812c3ccSTomohiro Kusumi case FUSE_INTERRUPT:
1945812c3ccSTomohiro Kusumi res = false;
1955812c3ccSTomohiro Kusumi break;
1965812c3ccSTomohiro Kusumi case FUSE_BMAP:
1975812c3ccSTomohiro Kusumi res = false;
1985812c3ccSTomohiro Kusumi break;
1995812c3ccSTomohiro Kusumi case FUSE_DESTROY:
2005812c3ccSTomohiro Kusumi res = (len == 0);
2015812c3ccSTomohiro Kusumi break;
2025812c3ccSTomohiro Kusumi case FUSE_IOCTL:
2035812c3ccSTomohiro Kusumi res = false;
2045812c3ccSTomohiro Kusumi break;
2055812c3ccSTomohiro Kusumi case FUSE_POLL:
2065812c3ccSTomohiro Kusumi res = false;
2075812c3ccSTomohiro Kusumi break;
2085812c3ccSTomohiro Kusumi case FUSE_NOTIFY_REPLY:
2095812c3ccSTomohiro Kusumi res = false;
2105812c3ccSTomohiro Kusumi break;
2115812c3ccSTomohiro Kusumi case FUSE_BATCH_FORGET:
2125812c3ccSTomohiro Kusumi res = false;
2135812c3ccSTomohiro Kusumi break;
2145812c3ccSTomohiro Kusumi case FUSE_FALLOCATE:
2155812c3ccSTomohiro Kusumi res = false;
2165812c3ccSTomohiro Kusumi break;
2175812c3ccSTomohiro Kusumi case FUSE_READDIRPLUS:
2185812c3ccSTomohiro Kusumi res = false;
2195812c3ccSTomohiro Kusumi break;
2205812c3ccSTomohiro Kusumi case FUSE_RENAME2:
2215812c3ccSTomohiro Kusumi res = false;
2225812c3ccSTomohiro Kusumi break;
2235812c3ccSTomohiro Kusumi case FUSE_LSEEK:
2245812c3ccSTomohiro Kusumi res = false;
2255812c3ccSTomohiro Kusumi break;
2265812c3ccSTomohiro Kusumi case FUSE_COPY_FILE_RANGE:
2275812c3ccSTomohiro Kusumi res = false;
2285812c3ccSTomohiro Kusumi break;
2295812c3ccSTomohiro Kusumi default:
2305812c3ccSTomohiro Kusumi fuse_panic("Invalid opcode %d", ihd->opcode);
2315812c3ccSTomohiro Kusumi break;
2325812c3ccSTomohiro Kusumi }
2335812c3ccSTomohiro Kusumi
2345812c3ccSTomohiro Kusumi if (!res)
2355812c3ccSTomohiro Kusumi return -1;
2365812c3ccSTomohiro Kusumi return 0;
2375812c3ccSTomohiro Kusumi }
2385812c3ccSTomohiro Kusumi
2395812c3ccSTomohiro Kusumi const char*
fuse_get_ops(int op)2405812c3ccSTomohiro Kusumi fuse_get_ops(int op)
2415812c3ccSTomohiro Kusumi {
2425812c3ccSTomohiro Kusumi switch (op) {
2435812c3ccSTomohiro Kusumi case FUSE_LOOKUP:
2445812c3ccSTomohiro Kusumi return "FUSE_LOOKUP";
2455812c3ccSTomohiro Kusumi case FUSE_FORGET:
2465812c3ccSTomohiro Kusumi return "FUSE_FORGET";
2475812c3ccSTomohiro Kusumi case FUSE_GETATTR:
2485812c3ccSTomohiro Kusumi return "FUSE_GETATTR";
2495812c3ccSTomohiro Kusumi case FUSE_SETATTR:
2505812c3ccSTomohiro Kusumi return "FUSE_SETATTR";
2515812c3ccSTomohiro Kusumi case FUSE_READLINK:
2525812c3ccSTomohiro Kusumi return "FUSE_READLINK";
2535812c3ccSTomohiro Kusumi case FUSE_SYMLINK:
2545812c3ccSTomohiro Kusumi return "FUSE_SYMLINK";
2555812c3ccSTomohiro Kusumi case FUSE_MKNOD:
2565812c3ccSTomohiro Kusumi return "FUSE_MKNOD";
2575812c3ccSTomohiro Kusumi case FUSE_MKDIR:
2585812c3ccSTomohiro Kusumi return "FUSE_MKDIR";
2595812c3ccSTomohiro Kusumi case FUSE_UNLINK:
2605812c3ccSTomohiro Kusumi return "FUSE_UNLINK";
2615812c3ccSTomohiro Kusumi case FUSE_RMDIR:
2625812c3ccSTomohiro Kusumi return "FUSE_RMDIR";
2635812c3ccSTomohiro Kusumi case FUSE_RENAME:
2645812c3ccSTomohiro Kusumi return "FUSE_RENAME";
2655812c3ccSTomohiro Kusumi case FUSE_LINK:
2665812c3ccSTomohiro Kusumi return "FUSE_LINK";
2675812c3ccSTomohiro Kusumi case FUSE_OPEN:
2685812c3ccSTomohiro Kusumi return "FUSE_OPEN";
2695812c3ccSTomohiro Kusumi case FUSE_READ:
2705812c3ccSTomohiro Kusumi return "FUSE_READ";
2715812c3ccSTomohiro Kusumi case FUSE_WRITE:
2725812c3ccSTomohiro Kusumi return "FUSE_WRITE";
2735812c3ccSTomohiro Kusumi case FUSE_STATFS:
2745812c3ccSTomohiro Kusumi return "FUSE_STATFS";
2755812c3ccSTomohiro Kusumi case FUSE_RELEASE:
2765812c3ccSTomohiro Kusumi return "FUSE_RELEASE";
2775812c3ccSTomohiro Kusumi case FUSE_FSYNC:
2785812c3ccSTomohiro Kusumi return "FUSE_FSYNC";
2795812c3ccSTomohiro Kusumi case FUSE_SETXATTR:
2805812c3ccSTomohiro Kusumi return "FUSE_SETXATTR";
2815812c3ccSTomohiro Kusumi case FUSE_GETXATTR:
2825812c3ccSTomohiro Kusumi return "FUSE_GETXATTR";
2835812c3ccSTomohiro Kusumi case FUSE_LISTXATTR:
2845812c3ccSTomohiro Kusumi return "FUSE_LISTXATTR";
2855812c3ccSTomohiro Kusumi case FUSE_REMOVEXATTR:
2865812c3ccSTomohiro Kusumi return "FUSE_REMOVEXATTR";
2875812c3ccSTomohiro Kusumi case FUSE_FLUSH:
2885812c3ccSTomohiro Kusumi return "FUSE_FLUSH";
2895812c3ccSTomohiro Kusumi case FUSE_INIT:
2905812c3ccSTomohiro Kusumi return "FUSE_INIT";
2915812c3ccSTomohiro Kusumi case FUSE_OPENDIR:
2925812c3ccSTomohiro Kusumi return "FUSE_OPENDIR";
2935812c3ccSTomohiro Kusumi case FUSE_READDIR:
2945812c3ccSTomohiro Kusumi return "FUSE_READDIR";
2955812c3ccSTomohiro Kusumi case FUSE_RELEASEDIR:
2965812c3ccSTomohiro Kusumi return "FUSE_RELEASEDIR";
2975812c3ccSTomohiro Kusumi case FUSE_FSYNCDIR:
2985812c3ccSTomohiro Kusumi return "FUSE_FSYNCDIR";
2995812c3ccSTomohiro Kusumi case FUSE_GETLK:
3005812c3ccSTomohiro Kusumi return "FUSE_GETLK";
3015812c3ccSTomohiro Kusumi case FUSE_SETLK:
3025812c3ccSTomohiro Kusumi return "FUSE_SETLK";
3035812c3ccSTomohiro Kusumi case FUSE_SETLKW:
3045812c3ccSTomohiro Kusumi return "FUSE_SETLKW";
3055812c3ccSTomohiro Kusumi case FUSE_ACCESS:
3065812c3ccSTomohiro Kusumi return "FUSE_ACCESS";
3075812c3ccSTomohiro Kusumi case FUSE_CREATE:
3085812c3ccSTomohiro Kusumi return "FUSE_CREATE";
3095812c3ccSTomohiro Kusumi case FUSE_INTERRUPT:
3105812c3ccSTomohiro Kusumi return "FUSE_INTERRUPT";
3115812c3ccSTomohiro Kusumi case FUSE_BMAP:
3125812c3ccSTomohiro Kusumi return "FUSE_BMAP";
3135812c3ccSTomohiro Kusumi case FUSE_DESTROY:
3145812c3ccSTomohiro Kusumi return "FUSE_DESTROY";
3155812c3ccSTomohiro Kusumi case FUSE_IOCTL:
3165812c3ccSTomohiro Kusumi return "FUSE_IOCTL";
3175812c3ccSTomohiro Kusumi case FUSE_POLL:
3185812c3ccSTomohiro Kusumi return "FUSE_POLL";
3195812c3ccSTomohiro Kusumi case FUSE_NOTIFY_REPLY:
3205812c3ccSTomohiro Kusumi return "FUSE_NOTIFY_REPLY";
3215812c3ccSTomohiro Kusumi case FUSE_BATCH_FORGET:
3225812c3ccSTomohiro Kusumi return "FUSE_BATCH_FORGET";
3235812c3ccSTomohiro Kusumi case FUSE_FALLOCATE:
3245812c3ccSTomohiro Kusumi return "FUSE_FALLOCATE";
3255812c3ccSTomohiro Kusumi case FUSE_READDIRPLUS:
3265812c3ccSTomohiro Kusumi return "FUSE_READDIRPLUS";
3275812c3ccSTomohiro Kusumi case FUSE_RENAME2:
3285812c3ccSTomohiro Kusumi return "FUSE_RENAME2";
3295812c3ccSTomohiro Kusumi case FUSE_LSEEK:
3305812c3ccSTomohiro Kusumi return "FUSE_LSEEK";
3315812c3ccSTomohiro Kusumi case FUSE_COPY_FILE_RANGE:
3325812c3ccSTomohiro Kusumi return "FUSE_COPY_FILE_RANGE";
3335812c3ccSTomohiro Kusumi default:
3345812c3ccSTomohiro Kusumi fuse_panic("Invalid opcode %d", op);
3355812c3ccSTomohiro Kusumi break;
3365812c3ccSTomohiro Kusumi }
3375812c3ccSTomohiro Kusumi
3385812c3ccSTomohiro Kusumi return NULL;
3395812c3ccSTomohiro Kusumi }
340