1// Copyright 2016 the Go-FUSE Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package pathfs
6
7import (
8	"fmt"
9	"time"
10
11	"github.com/hanwen/go-fuse/v2/fuse"
12	"github.com/hanwen/go-fuse/v2/fuse/nodefs"
13)
14
15// NewReadonlyFileSystem returns a wrapper that only exposes read-only
16// operations.
17func NewReadonlyFileSystem(fs FileSystem) FileSystem {
18	return &readonlyFileSystem{fs}
19}
20
21type readonlyFileSystem struct {
22	FileSystem
23}
24
25func (fs *readonlyFileSystem) GetAttr(name string, context *fuse.Context) (*fuse.Attr, fuse.Status) {
26	return fs.FileSystem.GetAttr(name, context)
27}
28
29func (fs *readonlyFileSystem) Readlink(name string, context *fuse.Context) (string, fuse.Status) {
30	return fs.FileSystem.Readlink(name, context)
31}
32
33func (fs *readonlyFileSystem) Mknod(name string, mode uint32, dev uint32, context *fuse.Context) fuse.Status {
34	return fuse.EPERM
35}
36
37func (fs *readonlyFileSystem) Mkdir(name string, mode uint32, context *fuse.Context) fuse.Status {
38	return fuse.EPERM
39}
40
41func (fs *readonlyFileSystem) Unlink(name string, context *fuse.Context) (code fuse.Status) {
42	return fuse.EPERM
43}
44
45func (fs *readonlyFileSystem) Rmdir(name string, context *fuse.Context) (code fuse.Status) {
46	return fuse.EPERM
47}
48
49func (fs *readonlyFileSystem) Symlink(value string, linkName string, context *fuse.Context) (code fuse.Status) {
50	return fuse.EPERM
51}
52
53func (fs *readonlyFileSystem) Rename(oldName string, newName string, context *fuse.Context) (code fuse.Status) {
54	return fuse.EPERM
55}
56
57func (fs *readonlyFileSystem) Link(oldName string, newName string, context *fuse.Context) (code fuse.Status) {
58	return fuse.EPERM
59}
60
61func (fs *readonlyFileSystem) Chmod(name string, mode uint32, context *fuse.Context) (code fuse.Status) {
62	return fuse.EPERM
63}
64
65func (fs *readonlyFileSystem) Chown(name string, uid uint32, gid uint32, context *fuse.Context) (code fuse.Status) {
66	return fuse.EPERM
67}
68
69func (fs *readonlyFileSystem) Truncate(name string, offset uint64, context *fuse.Context) (code fuse.Status) {
70	return fuse.EPERM
71}
72
73func (fs *readonlyFileSystem) Open(name string, flags uint32, context *fuse.Context) (file nodefs.File, code fuse.Status) {
74	if flags&fuse.O_ANYWRITE != 0 {
75		return nil, fuse.EPERM
76	}
77	file, code = fs.FileSystem.Open(name, flags, context)
78	return nodefs.NewReadOnlyFile(file), code
79}
80
81func (fs *readonlyFileSystem) OpenDir(name string, context *fuse.Context) (stream []fuse.DirEntry, status fuse.Status) {
82	return fs.FileSystem.OpenDir(name, context)
83}
84
85func (fs *readonlyFileSystem) OnMount(nodeFs *PathNodeFs) {
86	fs.FileSystem.OnMount(nodeFs)
87}
88
89func (fs *readonlyFileSystem) OnUnmount() {
90	fs.FileSystem.OnUnmount()
91}
92
93func (fs *readonlyFileSystem) String() string {
94	return fmt.Sprintf("readonlyFileSystem(%v)", fs.FileSystem)
95}
96
97func (fs *readonlyFileSystem) Access(name string, mode uint32, context *fuse.Context) (code fuse.Status) {
98	return fs.FileSystem.Access(name, mode, context)
99}
100
101func (fs *readonlyFileSystem) Create(name string, flags uint32, mode uint32, context *fuse.Context) (file nodefs.File, code fuse.Status) {
102	return nil, fuse.EPERM
103}
104
105func (fs *readonlyFileSystem) Utimens(name string, atime *time.Time, ctime *time.Time, context *fuse.Context) (code fuse.Status) {
106	return fuse.EPERM
107}
108
109func (fs *readonlyFileSystem) GetXAttr(name string, attr string, context *fuse.Context) ([]byte, fuse.Status) {
110	return fs.FileSystem.GetXAttr(name, attr, context)
111}
112
113func (fs *readonlyFileSystem) SetXAttr(name string, attr string, data []byte, flags int, context *fuse.Context) fuse.Status {
114	return fuse.EPERM
115}
116
117func (fs *readonlyFileSystem) ListXAttr(name string, context *fuse.Context) ([]string, fuse.Status) {
118	return fs.FileSystem.ListXAttr(name, context)
119}
120
121func (fs *readonlyFileSystem) RemoveXAttr(name string, attr string, context *fuse.Context) fuse.Status {
122	return fuse.EPERM
123}
124