Statistics
| Branch: | Tag: | Revision:

root / contrib / snf-pithos-tools / pithos / tools / lib / fuse.py @ a5cb2e20

History | View | Annotate | Download (22.2 kB)

1 49350be7 Giorgos Verigakis
# Copyright (c) 2008 Giorgos Verigakis <verigak@gmail.com>
2 2715ade4 Sofia Papagiannaki
#
3 49350be7 Giorgos Verigakis
# Permission to use, copy, modify, and distribute this software for any
4 49350be7 Giorgos Verigakis
# purpose with or without fee is hereby granted, provided that the above
5 49350be7 Giorgos Verigakis
# copyright notice and this permission notice appear in all copies.
6 2715ade4 Sofia Papagiannaki
#
7 49350be7 Giorgos Verigakis
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 49350be7 Giorgos Verigakis
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 49350be7 Giorgos Verigakis
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10 49350be7 Giorgos Verigakis
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 49350be7 Giorgos Verigakis
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12 49350be7 Giorgos Verigakis
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13 49350be7 Giorgos Verigakis
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14 49350be7 Giorgos Verigakis
15 49350be7 Giorgos Verigakis
from __future__ import division
16 49350be7 Giorgos Verigakis
17 49350be7 Giorgos Verigakis
from ctypes import *
18 49350be7 Giorgos Verigakis
from ctypes.util import find_library
19 49350be7 Giorgos Verigakis
from errno import *
20 49350be7 Giorgos Verigakis
from functools import partial
21 49350be7 Giorgos Verigakis
from os import strerror
22 49350be7 Giorgos Verigakis
from platform import machine, system
23 49350be7 Giorgos Verigakis
from stat import S_IFDIR
24 49350be7 Giorgos Verigakis
from traceback import print_exc
25 49350be7 Giorgos Verigakis
26 49350be7 Giorgos Verigakis
27 49350be7 Giorgos Verigakis
class c_timespec(Structure):
28 49350be7 Giorgos Verigakis
    _fields_ = [('tv_sec', c_long), ('tv_nsec', c_long)]
29 49350be7 Giorgos Verigakis
30 2715ade4 Sofia Papagiannaki
31 49350be7 Giorgos Verigakis
class c_utimbuf(Structure):
32 49350be7 Giorgos Verigakis
    _fields_ = [('actime', c_timespec), ('modtime', c_timespec)]
33 49350be7 Giorgos Verigakis
34 2715ade4 Sofia Papagiannaki
35 49350be7 Giorgos Verigakis
class c_stat(Structure):
36 49350be7 Giorgos Verigakis
    pass    # Platform dependent
37 49350be7 Giorgos Verigakis
38 49350be7 Giorgos Verigakis
_system = system()
39 49350be7 Giorgos Verigakis
if _system in ('Darwin', 'FreeBSD'):
40 2715ade4 Sofia Papagiannaki
    _libiconv = CDLL(
41 2715ade4 Sofia Papagiannaki
        find_library("iconv"), RTLD_GLOBAL)     # libfuse dependency
42 49350be7 Giorgos Verigakis
    ENOTSUP = 45
43 49350be7 Giorgos Verigakis
    c_dev_t = c_int32
44 49350be7 Giorgos Verigakis
    c_fsblkcnt_t = c_ulong
45 49350be7 Giorgos Verigakis
    c_fsfilcnt_t = c_ulong
46 49350be7 Giorgos Verigakis
    c_gid_t = c_uint32
47 49350be7 Giorgos Verigakis
    c_mode_t = c_uint16
48 49350be7 Giorgos Verigakis
    c_off_t = c_int64
49 49350be7 Giorgos Verigakis
    c_pid_t = c_int32
50 49350be7 Giorgos Verigakis
    c_uid_t = c_uint32
51 49350be7 Giorgos Verigakis
    setxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte),
52 2715ade4 Sofia Papagiannaki
                           c_size_t, c_int, c_uint32)
53 49350be7 Giorgos Verigakis
    getxattr_t = CFUNCTYPE(c_int, c_char_p, c_char_p, POINTER(c_byte),
54 2715ade4 Sofia Papagiannaki
                           c_size_t, c_uint32)
55 49350be7 Giorgos Verigakis
    c_stat._fields_ = [
56 49350be7 Giorgos Verigakis
        ('st_dev', c_dev_t),
57 49350be7 Giorgos Verigakis
        ('st_ino', c_uint32),
58 49350be7 Giorgos Verigakis
        ('st_mode', c_mode_t),
59 49350be7 Giorgos Verigakis
        ('st_nlink', c_uint16),
60 49350be7 Giorgos Verigakis
        ('st_uid', c_uid_t),
61 49350be7 Giorgos Verigakis
        ('st_gid', c_gid_t),
62 49350be7 Giorgos Verigakis
        ('st_rdev', c_dev_t),
63 49350be7 Giorgos Verigakis
        ('st_atimespec', c_timespec),
64 49350be7 Giorgos Verigakis
        ('st_mtimespec', c_timespec),
65 49350be7 Giorgos Verigakis
        ('st_ctimespec', c_timespec),
66 49350be7 Giorgos Verigakis
        ('st_size', c_off_t),
67 49350be7 Giorgos Verigakis
        ('st_blocks', c_int64),
68 49350be7 Giorgos Verigakis
        ('st_blksize', c_int32)]
69 49350be7 Giorgos Verigakis
elif _system == 'Linux':
70 49350be7 Giorgos Verigakis
    ENOTSUP = 95
71 49350be7 Giorgos Verigakis
    c_dev_t = c_ulonglong
72 49350be7 Giorgos Verigakis
    c_fsblkcnt_t = c_ulonglong
73 49350be7 Giorgos Verigakis
    c_fsfilcnt_t = c_ulonglong
74 49350be7 Giorgos Verigakis
    c_gid_t = c_uint
75 49350be7 Giorgos Verigakis
    c_mode_t = c_uint
76 49350be7 Giorgos Verigakis
    c_off_t = c_longlong
77 49350be7 Giorgos Verigakis
    c_pid_t = c_int
78 49350be7 Giorgos Verigakis
    c_uid_t = c_uint
79 2715ade4 Sofia Papagiannaki
    setxattr_t = CFUNCTYPE(
80 2715ade4 Sofia Papagiannaki
        c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t, c_int)
81 2715ade4 Sofia Papagiannaki
    getxattr_t = CFUNCTYPE(
82 2715ade4 Sofia Papagiannaki
        c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t)
83 2715ade4 Sofia Papagiannaki
84 49350be7 Giorgos Verigakis
    _machine = machine()
85 49350be7 Giorgos Verigakis
    if _machine == 'x86_64':
86 49350be7 Giorgos Verigakis
        c_stat._fields_ = [
87 49350be7 Giorgos Verigakis
            ('st_dev', c_dev_t),
88 49350be7 Giorgos Verigakis
            ('st_ino', c_ulong),
89 49350be7 Giorgos Verigakis
            ('st_nlink', c_ulong),
90 49350be7 Giorgos Verigakis
            ('st_mode', c_mode_t),
91 49350be7 Giorgos Verigakis
            ('st_uid', c_uid_t),
92 49350be7 Giorgos Verigakis
            ('st_gid', c_gid_t),
93 49350be7 Giorgos Verigakis
            ('__pad0', c_int),
94 49350be7 Giorgos Verigakis
            ('st_rdev', c_dev_t),
95 49350be7 Giorgos Verigakis
            ('st_size', c_off_t),
96 49350be7 Giorgos Verigakis
            ('st_blksize', c_long),
97 49350be7 Giorgos Verigakis
            ('st_blocks', c_long),
98 49350be7 Giorgos Verigakis
            ('st_atimespec', c_timespec),
99 49350be7 Giorgos Verigakis
            ('st_mtimespec', c_timespec),
100 49350be7 Giorgos Verigakis
            ('st_ctimespec', c_timespec)]
101 49350be7 Giorgos Verigakis
    elif _machine == 'ppc':
102 49350be7 Giorgos Verigakis
        c_stat._fields_ = [
103 49350be7 Giorgos Verigakis
            ('st_dev', c_dev_t),
104 49350be7 Giorgos Verigakis
            ('st_ino', c_ulonglong),
105 49350be7 Giorgos Verigakis
            ('st_mode', c_mode_t),
106 49350be7 Giorgos Verigakis
            ('st_nlink', c_uint),
107 49350be7 Giorgos Verigakis
            ('st_uid', c_uid_t),
108 49350be7 Giorgos Verigakis
            ('st_gid', c_gid_t),
109 49350be7 Giorgos Verigakis
            ('st_rdev', c_dev_t),
110 49350be7 Giorgos Verigakis
            ('__pad2', c_ushort),
111 49350be7 Giorgos Verigakis
            ('st_size', c_off_t),
112 49350be7 Giorgos Verigakis
            ('st_blksize', c_long),
113 49350be7 Giorgos Verigakis
            ('st_blocks', c_longlong),
114 49350be7 Giorgos Verigakis
            ('st_atimespec', c_timespec),
115 49350be7 Giorgos Verigakis
            ('st_mtimespec', c_timespec),
116 49350be7 Giorgos Verigakis
            ('st_ctimespec', c_timespec)]
117 49350be7 Giorgos Verigakis
    else:
118 49350be7 Giorgos Verigakis
        # i686, use as fallback for everything else
119 49350be7 Giorgos Verigakis
        c_stat._fields_ = [
120 49350be7 Giorgos Verigakis
            ('st_dev', c_dev_t),
121 49350be7 Giorgos Verigakis
            ('__pad1', c_ushort),
122 49350be7 Giorgos Verigakis
            ('__st_ino', c_ulong),
123 49350be7 Giorgos Verigakis
            ('st_mode', c_mode_t),
124 49350be7 Giorgos Verigakis
            ('st_nlink', c_uint),
125 49350be7 Giorgos Verigakis
            ('st_uid', c_uid_t),
126 49350be7 Giorgos Verigakis
            ('st_gid', c_gid_t),
127 49350be7 Giorgos Verigakis
            ('st_rdev', c_dev_t),
128 49350be7 Giorgos Verigakis
            ('__pad2', c_ushort),
129 49350be7 Giorgos Verigakis
            ('st_size', c_off_t),
130 49350be7 Giorgos Verigakis
            ('st_blksize', c_long),
131 49350be7 Giorgos Verigakis
            ('st_blocks', c_longlong),
132 49350be7 Giorgos Verigakis
            ('st_atimespec', c_timespec),
133 49350be7 Giorgos Verigakis
            ('st_mtimespec', c_timespec),
134 49350be7 Giorgos Verigakis
            ('st_ctimespec', c_timespec),
135 49350be7 Giorgos Verigakis
            ('st_ino', c_ulonglong)]
136 49350be7 Giorgos Verigakis
else:
137 49350be7 Giorgos Verigakis
    raise NotImplementedError('%s is not supported.' % _system)
138 49350be7 Giorgos Verigakis
139 49350be7 Giorgos Verigakis
140 49350be7 Giorgos Verigakis
class c_statvfs(Structure):
141 49350be7 Giorgos Verigakis
    _fields_ = [
142 49350be7 Giorgos Verigakis
        ('f_bsize', c_ulong),
143 49350be7 Giorgos Verigakis
        ('f_frsize', c_ulong),
144 49350be7 Giorgos Verigakis
        ('f_blocks', c_fsblkcnt_t),
145 49350be7 Giorgos Verigakis
        ('f_bfree', c_fsblkcnt_t),
146 49350be7 Giorgos Verigakis
        ('f_bavail', c_fsblkcnt_t),
147 49350be7 Giorgos Verigakis
        ('f_files', c_fsfilcnt_t),
148 49350be7 Giorgos Verigakis
        ('f_ffree', c_fsfilcnt_t),
149 49350be7 Giorgos Verigakis
        ('f_favail', c_fsfilcnt_t)]
150 49350be7 Giorgos Verigakis
151 49350be7 Giorgos Verigakis
if _system == 'FreeBSD':
152 49350be7 Giorgos Verigakis
    c_fsblkcnt_t = c_uint64
153 49350be7 Giorgos Verigakis
    c_fsfilcnt_t = c_uint64
154 2715ade4 Sofia Papagiannaki
    setxattr_t = CFUNCTYPE(
155 2715ade4 Sofia Papagiannaki
        c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t, c_int)
156 2715ade4 Sofia Papagiannaki
    getxattr_t = CFUNCTYPE(
157 2715ade4 Sofia Papagiannaki
        c_int, c_char_p, c_char_p, POINTER(c_byte), c_size_t)
158 2715ade4 Sofia Papagiannaki
159 49350be7 Giorgos Verigakis
    class c_statvfs(Structure):
160 49350be7 Giorgos Verigakis
        _fields_ = [
161 49350be7 Giorgos Verigakis
            ('f_bavail', c_fsblkcnt_t),
162 49350be7 Giorgos Verigakis
            ('f_bfree', c_fsblkcnt_t),
163 49350be7 Giorgos Verigakis
            ('f_blocks', c_fsblkcnt_t),
164 49350be7 Giorgos Verigakis
            ('f_favail', c_fsfilcnt_t),
165 49350be7 Giorgos Verigakis
            ('f_ffree', c_fsfilcnt_t),
166 49350be7 Giorgos Verigakis
            ('f_files', c_fsfilcnt_t),
167 49350be7 Giorgos Verigakis
            ('f_bsize', c_ulong),
168 49350be7 Giorgos Verigakis
            ('f_flag', c_ulong),
169 49350be7 Giorgos Verigakis
            ('f_frsize', c_ulong)]
170 49350be7 Giorgos Verigakis
171 2715ade4 Sofia Papagiannaki
172 49350be7 Giorgos Verigakis
class fuse_file_info(Structure):
173 49350be7 Giorgos Verigakis
    _fields_ = [
174 49350be7 Giorgos Verigakis
        ('flags', c_int),
175 49350be7 Giorgos Verigakis
        ('fh_old', c_ulong),
176 49350be7 Giorgos Verigakis
        ('writepage', c_int),
177 49350be7 Giorgos Verigakis
        ('direct_io', c_uint, 1),
178 49350be7 Giorgos Verigakis
        ('keep_cache', c_uint, 1),
179 49350be7 Giorgos Verigakis
        ('flush', c_uint, 1),
180 49350be7 Giorgos Verigakis
        ('padding', c_uint, 29),
181 49350be7 Giorgos Verigakis
        ('fh', c_uint64),
182 49350be7 Giorgos Verigakis
        ('lock_owner', c_uint64)]
183 49350be7 Giorgos Verigakis
184 2715ade4 Sofia Papagiannaki
185 49350be7 Giorgos Verigakis
class fuse_context(Structure):
186 49350be7 Giorgos Verigakis
    _fields_ = [
187 49350be7 Giorgos Verigakis
        ('fuse', c_voidp),
188 49350be7 Giorgos Verigakis
        ('uid', c_uid_t),
189 49350be7 Giorgos Verigakis
        ('gid', c_gid_t),
190 49350be7 Giorgos Verigakis
        ('pid', c_pid_t),
191 49350be7 Giorgos Verigakis
        ('private_data', c_voidp)]
192 49350be7 Giorgos Verigakis
193 2715ade4 Sofia Papagiannaki
194 49350be7 Giorgos Verigakis
class fuse_operations(Structure):
195 49350be7 Giorgos Verigakis
    _fields_ = [
196 49350be7 Giorgos Verigakis
        ('getattr', CFUNCTYPE(c_int, c_char_p, POINTER(c_stat))),
197 49350be7 Giorgos Verigakis
        ('readlink', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t)),
198 49350be7 Giorgos Verigakis
        ('getdir', c_voidp),    # Deprecated, use readdir
199 49350be7 Giorgos Verigakis
        ('mknod', CFUNCTYPE(c_int, c_char_p, c_mode_t, c_dev_t)),
200 49350be7 Giorgos Verigakis
        ('mkdir', CFUNCTYPE(c_int, c_char_p, c_mode_t)),
201 49350be7 Giorgos Verigakis
        ('unlink', CFUNCTYPE(c_int, c_char_p)),
202 49350be7 Giorgos Verigakis
        ('rmdir', CFUNCTYPE(c_int, c_char_p)),
203 49350be7 Giorgos Verigakis
        ('symlink', CFUNCTYPE(c_int, c_char_p, c_char_p)),
204 49350be7 Giorgos Verigakis
        ('rename', CFUNCTYPE(c_int, c_char_p, c_char_p)),
205 49350be7 Giorgos Verigakis
        ('link', CFUNCTYPE(c_int, c_char_p, c_char_p)),
206 49350be7 Giorgos Verigakis
        ('chmod', CFUNCTYPE(c_int, c_char_p, c_mode_t)),
207 49350be7 Giorgos Verigakis
        ('chown', CFUNCTYPE(c_int, c_char_p, c_uid_t, c_gid_t)),
208 49350be7 Giorgos Verigakis
        ('truncate', CFUNCTYPE(c_int, c_char_p, c_off_t)),
209 49350be7 Giorgos Verigakis
        ('utime', c_voidp),     # Deprecated, use utimens
210 49350be7 Giorgos Verigakis
        ('open', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))),
211 49350be7 Giorgos Verigakis
        ('read', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t, c_off_t,
212 2715ade4 Sofia Papagiannaki
                           POINTER(fuse_file_info))),
213 2715ade4 Sofia Papagiannaki
        (
214 2715ade4 Sofia Papagiannaki
            'write', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t, c_off_t,
215 49350be7 Giorgos Verigakis
            POINTER(fuse_file_info))),
216 49350be7 Giorgos Verigakis
        ('statfs', CFUNCTYPE(c_int, c_char_p, POINTER(c_statvfs))),
217 49350be7 Giorgos Verigakis
        ('flush', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))),
218 49350be7 Giorgos Verigakis
        ('release', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))),
219 49350be7 Giorgos Verigakis
        ('fsync', CFUNCTYPE(c_int, c_char_p, c_int, POINTER(fuse_file_info))),
220 49350be7 Giorgos Verigakis
        ('setxattr', setxattr_t),
221 49350be7 Giorgos Verigakis
        ('getxattr', getxattr_t),
222 49350be7 Giorgos Verigakis
        ('listxattr', CFUNCTYPE(c_int, c_char_p, POINTER(c_byte), c_size_t)),
223 49350be7 Giorgos Verigakis
        ('removexattr', CFUNCTYPE(c_int, c_char_p, c_char_p)),
224 49350be7 Giorgos Verigakis
        ('opendir', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))),
225 2715ade4 Sofia Papagiannaki
        (
226 2715ade4 Sofia Papagiannaki
            'readdir', CFUNCTYPE(c_int, c_char_p, c_voidp, CFUNCTYPE(c_int, c_voidp,
227 2715ade4 Sofia Papagiannaki
            c_char_p, POINTER(
228 2715ade4 Sofia Papagiannaki
                c_stat), c_off_t), c_off_t, POINTER(fuse_file_info))),
229 49350be7 Giorgos Verigakis
        ('releasedir', CFUNCTYPE(c_int, c_char_p, POINTER(fuse_file_info))),
230 2715ade4 Sofia Papagiannaki
        ('fsyncdir', CFUNCTYPE(c_int, c_char_p, c_int, POINTER(
231 2715ade4 Sofia Papagiannaki
            fuse_file_info))),
232 49350be7 Giorgos Verigakis
        ('init', CFUNCTYPE(c_voidp, c_voidp)),
233 49350be7 Giorgos Verigakis
        ('destroy', CFUNCTYPE(c_voidp, c_voidp)),
234 49350be7 Giorgos Verigakis
        ('access', CFUNCTYPE(c_int, c_char_p, c_int)),
235 2715ade4 Sofia Papagiannaki
        ('create', CFUNCTYPE(c_int, c_char_p, c_mode_t, POINTER(
236 2715ade4 Sofia Papagiannaki
            fuse_file_info))),
237 2715ade4 Sofia Papagiannaki
        ('ftruncate', CFUNCTYPE(c_int, c_char_p, c_off_t, POINTER(
238 2715ade4 Sofia Papagiannaki
            fuse_file_info))),
239 49350be7 Giorgos Verigakis
        ('fgetattr', CFUNCTYPE(c_int, c_char_p, POINTER(c_stat),
240 2715ade4 Sofia Papagiannaki
                               POINTER(fuse_file_info))),
241 2715ade4 Sofia Papagiannaki
        ('lock', CFUNCTYPE(
242 2715ade4 Sofia Papagiannaki
            c_int, c_char_p, POINTER(fuse_file_info), c_int, c_voidp)),
243 49350be7 Giorgos Verigakis
        ('utimens', CFUNCTYPE(c_int, c_char_p, POINTER(c_utimbuf))),
244 49350be7 Giorgos Verigakis
        ('bmap', CFUNCTYPE(c_int, c_char_p, c_size_t, POINTER(c_ulonglong)))]
245 49350be7 Giorgos Verigakis
246 49350be7 Giorgos Verigakis
247 49350be7 Giorgos Verigakis
def time_of_timespec(ts):
248 49350be7 Giorgos Verigakis
    return ts.tv_sec + ts.tv_nsec / 10 ** 9
249 49350be7 Giorgos Verigakis
250 2715ade4 Sofia Papagiannaki
251 49350be7 Giorgos Verigakis
def set_st_attrs(st, attrs):
252 49350be7 Giorgos Verigakis
    for key, val in attrs.items():
253 49350be7 Giorgos Verigakis
        if key in ('st_atime', 'st_mtime', 'st_ctime'):
254 49350be7 Giorgos Verigakis
            timespec = getattr(st, key + 'spec')
255 49350be7 Giorgos Verigakis
            timespec.tv_sec = int(val)
256 49350be7 Giorgos Verigakis
            timespec.tv_nsec = int((val - timespec.tv_sec) * 10 ** 9)
257 49350be7 Giorgos Verigakis
        elif hasattr(st, key):
258 49350be7 Giorgos Verigakis
            setattr(st, key, val)
259 49350be7 Giorgos Verigakis
260 49350be7 Giorgos Verigakis
261 49350be7 Giorgos Verigakis
_libfuse_path = find_library('fuse')
262 49350be7 Giorgos Verigakis
if not _libfuse_path:
263 49350be7 Giorgos Verigakis
    raise EnvironmentError('Unable to find libfuse')
264 49350be7 Giorgos Verigakis
_libfuse = CDLL(_libfuse_path)
265 49350be7 Giorgos Verigakis
_libfuse.fuse_get_context.restype = POINTER(fuse_context)
266 49350be7 Giorgos Verigakis
267 49350be7 Giorgos Verigakis
268 49350be7 Giorgos Verigakis
def fuse_get_context():
269 49350be7 Giorgos Verigakis
    """Returns a (uid, gid, pid) tuple"""
270 49350be7 Giorgos Verigakis
    ctxp = _libfuse.fuse_get_context()
271 49350be7 Giorgos Verigakis
    ctx = ctxp.contents
272 49350be7 Giorgos Verigakis
    return ctx.uid, ctx.gid, ctx.pid
273 49350be7 Giorgos Verigakis
274 49350be7 Giorgos Verigakis
275 49350be7 Giorgos Verigakis
class FuseOSError(OSError):
276 49350be7 Giorgos Verigakis
    def __init__(self, errno):
277 49350be7 Giorgos Verigakis
        super(FuseOSError, self).__init__(errno, strerror(errno))
278 49350be7 Giorgos Verigakis
279 49350be7 Giorgos Verigakis
280 49350be7 Giorgos Verigakis
class FUSE(object):
281 49350be7 Giorgos Verigakis
    """This class is the lower level interface and should not be subclassed
282 49350be7 Giorgos Verigakis
       under normal use. Its methods are called by fuse.
283 49350be7 Giorgos Verigakis
       Assumes API version 2.6 or later."""
284 2715ade4 Sofia Papagiannaki
285 49350be7 Giorgos Verigakis
    def __init__(self, operations, mountpoint, raw_fi=False, **kwargs):
286 49350be7 Giorgos Verigakis
        """Setting raw_fi to True will cause FUSE to pass the fuse_file_info
287 49350be7 Giorgos Verigakis
           class as is to Operations, instead of just the fh field.
288 49350be7 Giorgos Verigakis
           This gives you access to direct_io, keep_cache, etc."""
289 2715ade4 Sofia Papagiannaki
290 49350be7 Giorgos Verigakis
        self.operations = operations
291 49350be7 Giorgos Verigakis
        self.raw_fi = raw_fi
292 49350be7 Giorgos Verigakis
        args = ['fuse']
293 49350be7 Giorgos Verigakis
        if kwargs.pop('foreground', False):
294 49350be7 Giorgos Verigakis
            args.append('-f')
295 49350be7 Giorgos Verigakis
        if kwargs.pop('debug', False):
296 49350be7 Giorgos Verigakis
            args.append('-d')
297 49350be7 Giorgos Verigakis
        if kwargs.pop('nothreads', False):
298 49350be7 Giorgos Verigakis
            args.append('-s')
299 49350be7 Giorgos Verigakis
        kwargs.setdefault('fsname', operations.__class__.__name__)
300 49350be7 Giorgos Verigakis
        args.append('-o')
301 49350be7 Giorgos Verigakis
        args.append(','.join(key if val == True else '%s=%s' % (key, val)
302 2715ade4 Sofia Papagiannaki
                             for key, val in kwargs.items()))
303 49350be7 Giorgos Verigakis
        args.append(mountpoint)
304 49350be7 Giorgos Verigakis
        argv = (c_char_p * len(args))(*args)
305 2715ade4 Sofia Papagiannaki
306 49350be7 Giorgos Verigakis
        fuse_ops = fuse_operations()
307 49350be7 Giorgos Verigakis
        for name, prototype in fuse_operations._fields_:
308 49350be7 Giorgos Verigakis
            if prototype != c_voidp and getattr(operations, name, None):
309 49350be7 Giorgos Verigakis
                op = partial(self._wrapper_, getattr(self, name))
310 49350be7 Giorgos Verigakis
                setattr(fuse_ops, name, prototype(op))
311 49350be7 Giorgos Verigakis
        err = _libfuse.fuse_main_real(len(args), argv, pointer(fuse_ops),
312 2715ade4 Sofia Papagiannaki
                                      sizeof(fuse_ops), None)
313 49350be7 Giorgos Verigakis
        del self.operations     # Invoke the destructor
314 49350be7 Giorgos Verigakis
        if err:
315 49350be7 Giorgos Verigakis
            raise RuntimeError(err)
316 2715ade4 Sofia Papagiannaki
317 49350be7 Giorgos Verigakis
    def _wrapper_(self, func, *args, **kwargs):
318 49350be7 Giorgos Verigakis
        """Decorator for the methods that follow"""
319 49350be7 Giorgos Verigakis
        try:
320 49350be7 Giorgos Verigakis
            return func(*args, **kwargs) or 0
321 49350be7 Giorgos Verigakis
        except OSError, e:
322 49350be7 Giorgos Verigakis
            return -(e.errno or EFAULT)
323 49350be7 Giorgos Verigakis
        except:
324 49350be7 Giorgos Verigakis
            print_exc()
325 49350be7 Giorgos Verigakis
            return -EFAULT
326 2715ade4 Sofia Papagiannaki
327 49350be7 Giorgos Verigakis
    def getattr(self, path, buf):
328 49350be7 Giorgos Verigakis
        return self.fgetattr(path, buf, None)
329 2715ade4 Sofia Papagiannaki
330 49350be7 Giorgos Verigakis
    def readlink(self, path, buf, bufsize):
331 49350be7 Giorgos Verigakis
        ret = self.operations('readlink', path)
332 49350be7 Giorgos Verigakis
        data = create_string_buffer(ret[:bufsize - 1])
333 49350be7 Giorgos Verigakis
        memmove(buf, data, len(data))
334 49350be7 Giorgos Verigakis
        return 0
335 2715ade4 Sofia Papagiannaki
336 49350be7 Giorgos Verigakis
    def mknod(self, path, mode, dev):
337 49350be7 Giorgos Verigakis
        return self.operations('mknod', path, mode, dev)
338 2715ade4 Sofia Papagiannaki
339 49350be7 Giorgos Verigakis
    def mkdir(self, path, mode):
340 49350be7 Giorgos Verigakis
        return self.operations('mkdir', path, mode)
341 2715ade4 Sofia Papagiannaki
342 49350be7 Giorgos Verigakis
    def unlink(self, path):
343 49350be7 Giorgos Verigakis
        return self.operations('unlink', path)
344 2715ade4 Sofia Papagiannaki
345 49350be7 Giorgos Verigakis
    def rmdir(self, path):
346 49350be7 Giorgos Verigakis
        return self.operations('rmdir', path)
347 2715ade4 Sofia Papagiannaki
348 49350be7 Giorgos Verigakis
    def symlink(self, source, target):
349 49350be7 Giorgos Verigakis
        return self.operations('symlink', target, source)
350 2715ade4 Sofia Papagiannaki
351 49350be7 Giorgos Verigakis
    def rename(self, old, new):
352 49350be7 Giorgos Verigakis
        return self.operations('rename', old, new)
353 2715ade4 Sofia Papagiannaki
354 49350be7 Giorgos Verigakis
    def link(self, source, target):
355 49350be7 Giorgos Verigakis
        return self.operations('link', target, source)
356 2715ade4 Sofia Papagiannaki
357 49350be7 Giorgos Verigakis
    def chmod(self, path, mode):
358 49350be7 Giorgos Verigakis
        return self.operations('chmod', path, mode)
359 2715ade4 Sofia Papagiannaki
360 49350be7 Giorgos Verigakis
    def chown(self, path, uid, gid):
361 49350be7 Giorgos Verigakis
        # Check if any of the arguments is a -1 that has overflowed
362 49350be7 Giorgos Verigakis
        if c_uid_t(uid + 1).value == 0:
363 49350be7 Giorgos Verigakis
            uid = -1
364 49350be7 Giorgos Verigakis
        if c_gid_t(gid + 1).value == 0:
365 49350be7 Giorgos Verigakis
            gid = -1
366 49350be7 Giorgos Verigakis
        return self.operations('chown', path, uid, gid)
367 2715ade4 Sofia Papagiannaki
368 49350be7 Giorgos Verigakis
    def truncate(self, path, length):
369 49350be7 Giorgos Verigakis
        return self.operations('truncate', path, length)
370 2715ade4 Sofia Papagiannaki
371 49350be7 Giorgos Verigakis
    def open(self, path, fip):
372 49350be7 Giorgos Verigakis
        fi = fip.contents
373 49350be7 Giorgos Verigakis
        if self.raw_fi:
374 49350be7 Giorgos Verigakis
            return self.operations('open', path, fi)
375 49350be7 Giorgos Verigakis
        else:
376 49350be7 Giorgos Verigakis
            fi.fh = self.operations('open', path, fi.flags)
377 49350be7 Giorgos Verigakis
            return 0
378 2715ade4 Sofia Papagiannaki
379 49350be7 Giorgos Verigakis
    def read(self, path, buf, size, offset, fip):
380 49350be7 Giorgos Verigakis
        fh = fip.contents if self.raw_fi else fip.contents.fh
381 49350be7 Giorgos Verigakis
        ret = self.operations('read', path, size, offset, fh)
382 49350be7 Giorgos Verigakis
        if not ret:
383 49350be7 Giorgos Verigakis
            return 0
384 49350be7 Giorgos Verigakis
        data = create_string_buffer(ret[:size], size)
385 49350be7 Giorgos Verigakis
        memmove(buf, data, size)
386 49350be7 Giorgos Verigakis
        return size
387 2715ade4 Sofia Papagiannaki
388 49350be7 Giorgos Verigakis
    def write(self, path, buf, size, offset, fip):
389 49350be7 Giorgos Verigakis
        data = string_at(buf, size)
390 49350be7 Giorgos Verigakis
        fh = fip.contents if self.raw_fi else fip.contents.fh
391 49350be7 Giorgos Verigakis
        return self.operations('write', path, data, offset, fh)
392 2715ade4 Sofia Papagiannaki
393 49350be7 Giorgos Verigakis
    def statfs(self, path, buf):
394 49350be7 Giorgos Verigakis
        stv = buf.contents
395 49350be7 Giorgos Verigakis
        attrs = self.operations('statfs', path)
396 49350be7 Giorgos Verigakis
        for key, val in attrs.items():
397 49350be7 Giorgos Verigakis
            if hasattr(stv, key):
398 49350be7 Giorgos Verigakis
                setattr(stv, key, val)
399 49350be7 Giorgos Verigakis
        return 0
400 2715ade4 Sofia Papagiannaki
401 49350be7 Giorgos Verigakis
    def flush(self, path, fip):
402 49350be7 Giorgos Verigakis
        fh = fip.contents if self.raw_fi else fip.contents.fh
403 49350be7 Giorgos Verigakis
        return self.operations('flush', path, fh)
404 2715ade4 Sofia Papagiannaki
405 49350be7 Giorgos Verigakis
    def release(self, path, fip):
406 49350be7 Giorgos Verigakis
        fh = fip.contents if self.raw_fi else fip.contents.fh
407 49350be7 Giorgos Verigakis
        return self.operations('release', path, fh)
408 2715ade4 Sofia Papagiannaki
409 49350be7 Giorgos Verigakis
    def fsync(self, path, datasync, fip):
410 49350be7 Giorgos Verigakis
        fh = fip.contents if self.raw_fi else fip.contents.fh
411 49350be7 Giorgos Verigakis
        return self.operations('fsync', path, datasync, fh)
412 2715ade4 Sofia Papagiannaki
413 49350be7 Giorgos Verigakis
    def setxattr(self, path, name, value, size, options, *args):
414 49350be7 Giorgos Verigakis
        data = string_at(value, size)
415 49350be7 Giorgos Verigakis
        return self.operations('setxattr', path, name, data, options, *args)
416 2715ade4 Sofia Papagiannaki
417 49350be7 Giorgos Verigakis
    def getxattr(self, path, name, value, size, *args):
418 49350be7 Giorgos Verigakis
        ret = self.operations('getxattr', path, name, *args)
419 49350be7 Giorgos Verigakis
        retsize = len(ret)
420 49350be7 Giorgos Verigakis
        buf = create_string_buffer(ret, retsize)    # Does not add trailing 0
421 49350be7 Giorgos Verigakis
        if bool(value):
422 49350be7 Giorgos Verigakis
            if retsize > size:
423 49350be7 Giorgos Verigakis
                return -ERANGE
424 49350be7 Giorgos Verigakis
            memmove(value, buf, retsize)
425 49350be7 Giorgos Verigakis
        return retsize
426 2715ade4 Sofia Papagiannaki
427 49350be7 Giorgos Verigakis
    def listxattr(self, path, namebuf, size):
428 49350be7 Giorgos Verigakis
        ret = self.operations('listxattr', path)
429 49350be7 Giorgos Verigakis
        buf = create_string_buffer('\x00'.join(ret)) if ret else ''
430 49350be7 Giorgos Verigakis
        bufsize = len(buf)
431 49350be7 Giorgos Verigakis
        if bool(namebuf):
432 49350be7 Giorgos Verigakis
            if bufsize > size:
433 49350be7 Giorgos Verigakis
                return -ERANGE
434 49350be7 Giorgos Verigakis
            memmove(namebuf, buf, bufsize)
435 49350be7 Giorgos Verigakis
        return bufsize
436 2715ade4 Sofia Papagiannaki
437 49350be7 Giorgos Verigakis
    def removexattr(self, path, name):
438 49350be7 Giorgos Verigakis
        return self.operations('removexattr', path, name)
439 2715ade4 Sofia Papagiannaki
440 49350be7 Giorgos Verigakis
    def opendir(self, path, fip):
441 49350be7 Giorgos Verigakis
        # Ignore raw_fi
442 49350be7 Giorgos Verigakis
        fip.contents.fh = self.operations('opendir', path)
443 49350be7 Giorgos Verigakis
        return 0
444 2715ade4 Sofia Papagiannaki
445 49350be7 Giorgos Verigakis
    def readdir(self, path, buf, filler, offset, fip):
446 49350be7 Giorgos Verigakis
        # Ignore raw_fi
447 49350be7 Giorgos Verigakis
        for item in self.operations('readdir', path, fip.contents.fh):
448 49350be7 Giorgos Verigakis
            if isinstance(item, (str, unicode)):
449 49350be7 Giorgos Verigakis
                name, st, offset = item, None, 0
450 49350be7 Giorgos Verigakis
            else:
451 49350be7 Giorgos Verigakis
                name, attrs, offset = item
452 49350be7 Giorgos Verigakis
                if attrs:
453 49350be7 Giorgos Verigakis
                    st = c_stat()
454 49350be7 Giorgos Verigakis
                    set_st_attrs(st, attrs)
455 49350be7 Giorgos Verigakis
                else:
456 49350be7 Giorgos Verigakis
                    st = None
457 49350be7 Giorgos Verigakis
            if filler(buf, name, st, offset) != 0:
458 49350be7 Giorgos Verigakis
                break
459 49350be7 Giorgos Verigakis
        return 0
460 2715ade4 Sofia Papagiannaki
461 49350be7 Giorgos Verigakis
    def releasedir(self, path, fip):
462 49350be7 Giorgos Verigakis
        # Ignore raw_fi
463 49350be7 Giorgos Verigakis
        return self.operations('releasedir', path, fip.contents.fh)
464 2715ade4 Sofia Papagiannaki
465 49350be7 Giorgos Verigakis
    def fsyncdir(self, path, datasync, fip):
466 49350be7 Giorgos Verigakis
        # Ignore raw_fi
467 49350be7 Giorgos Verigakis
        return self.operations('fsyncdir', path, datasync, fip.contents.fh)
468 2715ade4 Sofia Papagiannaki
469 49350be7 Giorgos Verigakis
    def init(self, conn):
470 49350be7 Giorgos Verigakis
        return self.operations('init', '/')
471 2715ade4 Sofia Papagiannaki
472 49350be7 Giorgos Verigakis
    def destroy(self, private_data):
473 49350be7 Giorgos Verigakis
        return self.operations('destroy', '/')
474 2715ade4 Sofia Papagiannaki
475 49350be7 Giorgos Verigakis
    def access(self, path, amode):
476 49350be7 Giorgos Verigakis
        return self.operations('access', path, amode)
477 2715ade4 Sofia Papagiannaki
478 49350be7 Giorgos Verigakis
    def create(self, path, mode, fip):
479 49350be7 Giorgos Verigakis
        fi = fip.contents
480 49350be7 Giorgos Verigakis
        if self.raw_fi:
481 49350be7 Giorgos Verigakis
            return self.operations('create', path, mode, fi)
482 49350be7 Giorgos Verigakis
        else:
483 49350be7 Giorgos Verigakis
            fi.fh = self.operations('create', path, mode)
484 49350be7 Giorgos Verigakis
            return 0
485 2715ade4 Sofia Papagiannaki
486 49350be7 Giorgos Verigakis
    def ftruncate(self, path, length, fip):
487 49350be7 Giorgos Verigakis
        fh = fip.contents if self.raw_fi else fip.contents.fh
488 49350be7 Giorgos Verigakis
        return self.operations('truncate', path, length, fh)
489 2715ade4 Sofia Papagiannaki
490 49350be7 Giorgos Verigakis
    def fgetattr(self, path, buf, fip):
491 49350be7 Giorgos Verigakis
        memset(buf, 0, sizeof(c_stat))
492 49350be7 Giorgos Verigakis
        st = buf.contents
493 49350be7 Giorgos Verigakis
        fh = fip and (fip.contents if self.raw_fi else fip.contents.fh)
494 49350be7 Giorgos Verigakis
        attrs = self.operations('getattr', path, fh)
495 49350be7 Giorgos Verigakis
        set_st_attrs(st, attrs)
496 49350be7 Giorgos Verigakis
        return 0
497 2715ade4 Sofia Papagiannaki
498 49350be7 Giorgos Verigakis
    def lock(self, path, fip, cmd, lock):
499 49350be7 Giorgos Verigakis
        fh = fip.contents if self.raw_fi else fip.contents.fh
500 49350be7 Giorgos Verigakis
        return self.operations('lock', path, fh, cmd, lock)
501 2715ade4 Sofia Papagiannaki
502 49350be7 Giorgos Verigakis
    def utimens(self, path, buf):
503 49350be7 Giorgos Verigakis
        if buf:
504 49350be7 Giorgos Verigakis
            atime = time_of_timespec(buf.contents.actime)
505 49350be7 Giorgos Verigakis
            mtime = time_of_timespec(buf.contents.modtime)
506 49350be7 Giorgos Verigakis
            times = (atime, mtime)
507 49350be7 Giorgos Verigakis
        else:
508 49350be7 Giorgos Verigakis
            times = None
509 49350be7 Giorgos Verigakis
        return self.operations('utimens', path, times)
510 2715ade4 Sofia Papagiannaki
511 49350be7 Giorgos Verigakis
    def bmap(self, path, blocksize, idx):
512 49350be7 Giorgos Verigakis
        return self.operations('bmap', path, blocksize, idx)
513 49350be7 Giorgos Verigakis
514 49350be7 Giorgos Verigakis
515 49350be7 Giorgos Verigakis
class Operations(object):
516 49350be7 Giorgos Verigakis
    """This class should be subclassed and passed as an argument to FUSE on
517 49350be7 Giorgos Verigakis
       initialization. All operations should raise a FuseOSError exception
518 49350be7 Giorgos Verigakis
       on error.
519 2715ade4 Sofia Papagiannaki

520 49350be7 Giorgos Verigakis
       When in doubt of what an operation should do, check the FUSE header
521 49350be7 Giorgos Verigakis
       file or the corresponding system call man page."""
522 2715ade4 Sofia Papagiannaki
523 49350be7 Giorgos Verigakis
    def __call__(self, op, *args):
524 49350be7 Giorgos Verigakis
        if not hasattr(self, op):
525 49350be7 Giorgos Verigakis
            raise FuseOSError(EFAULT)
526 49350be7 Giorgos Verigakis
        return getattr(self, op)(*args)
527 2715ade4 Sofia Papagiannaki
528 49350be7 Giorgos Verigakis
    def access(self, path, amode):
529 49350be7 Giorgos Verigakis
        return 0
530 2715ade4 Sofia Papagiannaki
531 49350be7 Giorgos Verigakis
    bmap = None
532 2715ade4 Sofia Papagiannaki
533 49350be7 Giorgos Verigakis
    def chmod(self, path, mode):
534 49350be7 Giorgos Verigakis
        raise FuseOSError(EROFS)
535 2715ade4 Sofia Papagiannaki
536 49350be7 Giorgos Verigakis
    def chown(self, path, uid, gid):
537 49350be7 Giorgos Verigakis
        raise FuseOSError(EROFS)
538 2715ade4 Sofia Papagiannaki
539 49350be7 Giorgos Verigakis
    def create(self, path, mode, fi=None):
540 49350be7 Giorgos Verigakis
        """When raw_fi is False (default case), fi is None and create should
541 49350be7 Giorgos Verigakis
           return a numerical file handle.
542 49350be7 Giorgos Verigakis
           When raw_fi is True the file handle should be set directly by create
543 49350be7 Giorgos Verigakis
           and return 0."""
544 49350be7 Giorgos Verigakis
        raise FuseOSError(EROFS)
545 2715ade4 Sofia Papagiannaki
546 49350be7 Giorgos Verigakis
    def destroy(self, path):
547 49350be7 Giorgos Verigakis
        """Called on filesystem destruction. Path is always /"""
548 49350be7 Giorgos Verigakis
        pass
549 2715ade4 Sofia Papagiannaki
550 49350be7 Giorgos Verigakis
    def flush(self, path, fh):
551 49350be7 Giorgos Verigakis
        return 0
552 2715ade4 Sofia Papagiannaki
553 49350be7 Giorgos Verigakis
    def fsync(self, path, datasync, fh):
554 49350be7 Giorgos Verigakis
        return 0
555 2715ade4 Sofia Papagiannaki
556 49350be7 Giorgos Verigakis
    def fsyncdir(self, path, datasync, fh):
557 49350be7 Giorgos Verigakis
        return 0
558 2715ade4 Sofia Papagiannaki
559 49350be7 Giorgos Verigakis
    def getattr(self, path, fh=None):
560 49350be7 Giorgos Verigakis
        """Returns a dictionary with keys identical to the stat C structure
561 49350be7 Giorgos Verigakis
           of stat(2).
562 49350be7 Giorgos Verigakis
           st_atime, st_mtime and st_ctime should be floats.
563 49350be7 Giorgos Verigakis
           NOTE: There is an incombatibility between Linux and Mac OS X concerning
564 49350be7 Giorgos Verigakis
           st_nlink of directories. Mac OS X counts all files inside the directory,
565 49350be7 Giorgos Verigakis
           while Linux counts only the subdirectories."""
566 2715ade4 Sofia Papagiannaki
567 49350be7 Giorgos Verigakis
        if path != '/':
568 49350be7 Giorgos Verigakis
            raise FuseOSError(ENOENT)
569 49350be7 Giorgos Verigakis
        return dict(st_mode=(S_IFDIR | 0755), st_nlink=2)
570 2715ade4 Sofia Papagiannaki
571 49350be7 Giorgos Verigakis
    def getxattr(self, path, name, position=0):
572 49350be7 Giorgos Verigakis
        raise FuseOSError(ENOTSUP)
573 2715ade4 Sofia Papagiannaki
574 49350be7 Giorgos Verigakis
    def init(self, path):
575 49350be7 Giorgos Verigakis
        """Called on filesystem initialization. Path is always /
576 49350be7 Giorgos Verigakis
           Use it instead of __init__ if you start threads on initialization."""
577 49350be7 Giorgos Verigakis
        pass
578 2715ade4 Sofia Papagiannaki
579 49350be7 Giorgos Verigakis
    def link(self, target, source):
580 49350be7 Giorgos Verigakis
        raise FuseOSError(EROFS)
581 2715ade4 Sofia Papagiannaki
582 49350be7 Giorgos Verigakis
    def listxattr(self, path):
583 49350be7 Giorgos Verigakis
        return []
584 2715ade4 Sofia Papagiannaki
585 49350be7 Giorgos Verigakis
    lock = None
586 2715ade4 Sofia Papagiannaki
587 49350be7 Giorgos Verigakis
    def mkdir(self, path, mode):
588 49350be7 Giorgos Verigakis
        raise FuseOSError(EROFS)
589 2715ade4 Sofia Papagiannaki
590 49350be7 Giorgos Verigakis
    def mknod(self, path, mode, dev):
591 49350be7 Giorgos Verigakis
        raise FuseOSError(EROFS)
592 2715ade4 Sofia Papagiannaki
593 49350be7 Giorgos Verigakis
    def open(self, path, flags):
594 49350be7 Giorgos Verigakis
        """When raw_fi is False (default case), open should return a numerical
595 49350be7 Giorgos Verigakis
           file handle.
596 49350be7 Giorgos Verigakis
           When raw_fi is True the signature of open becomes:
597 49350be7 Giorgos Verigakis
               open(self, path, fi)
598 49350be7 Giorgos Verigakis
           and the file handle should be set directly."""
599 49350be7 Giorgos Verigakis
        return 0
600 2715ade4 Sofia Papagiannaki
601 49350be7 Giorgos Verigakis
    def opendir(self, path):
602 49350be7 Giorgos Verigakis
        """Returns a numerical file handle."""
603 49350be7 Giorgos Verigakis
        return 0
604 2715ade4 Sofia Papagiannaki
605 49350be7 Giorgos Verigakis
    def read(self, path, size, offset, fh):
606 49350be7 Giorgos Verigakis
        """Returns a string containing the data requested."""
607 49350be7 Giorgos Verigakis
        raise FuseOSError(EIO)
608 2715ade4 Sofia Papagiannaki
609 49350be7 Giorgos Verigakis
    def readdir(self, path, fh):
610 49350be7 Giorgos Verigakis
        """Can return either a list of names, or a list of (name, attrs, offset)
611 49350be7 Giorgos Verigakis
           tuples. attrs is a dict as in getattr."""
612 49350be7 Giorgos Verigakis
        return ['.', '..']
613 2715ade4 Sofia Papagiannaki
614 49350be7 Giorgos Verigakis
    def readlink(self, path):
615 49350be7 Giorgos Verigakis
        raise FuseOSError(ENOENT)
616 2715ade4 Sofia Papagiannaki
617 49350be7 Giorgos Verigakis
    def release(self, path, fh):
618 49350be7 Giorgos Verigakis
        return 0
619 2715ade4 Sofia Papagiannaki
620 49350be7 Giorgos Verigakis
    def releasedir(self, path, fh):
621 49350be7 Giorgos Verigakis
        return 0
622 2715ade4 Sofia Papagiannaki
623 49350be7 Giorgos Verigakis
    def removexattr(self, path, name):
624 49350be7 Giorgos Verigakis
        raise FuseOSError(ENOTSUP)
625 2715ade4 Sofia Papagiannaki
626 49350be7 Giorgos Verigakis
    def rename(self, old, new):
627 49350be7 Giorgos Verigakis
        raise FuseOSError(EROFS)
628 2715ade4 Sofia Papagiannaki
629 49350be7 Giorgos Verigakis
    def rmdir(self, path):
630 49350be7 Giorgos Verigakis
        raise FuseOSError(EROFS)
631 2715ade4 Sofia Papagiannaki
632 49350be7 Giorgos Verigakis
    def setxattr(self, path, name, value, options, position=0):
633 49350be7 Giorgos Verigakis
        raise FuseOSError(ENOTSUP)
634 2715ade4 Sofia Papagiannaki
635 49350be7 Giorgos Verigakis
    def statfs(self, path):
636 49350be7 Giorgos Verigakis
        """Returns a dictionary with keys identical to the statvfs C structure
637 49350be7 Giorgos Verigakis
           of statvfs(3).
638 49350be7 Giorgos Verigakis
           On Mac OS X f_bsize and f_frsize must be a power of 2 (minimum 512)."""
639 49350be7 Giorgos Verigakis
        return {}
640 2715ade4 Sofia Papagiannaki
641 49350be7 Giorgos Verigakis
    def symlink(self, target, source):
642 49350be7 Giorgos Verigakis
        raise FuseOSError(EROFS)
643 2715ade4 Sofia Papagiannaki
644 49350be7 Giorgos Verigakis
    def truncate(self, path, length, fh=None):
645 49350be7 Giorgos Verigakis
        raise FuseOSError(EROFS)
646 2715ade4 Sofia Papagiannaki
647 49350be7 Giorgos Verigakis
    def unlink(self, path):
648 49350be7 Giorgos Verigakis
        raise FuseOSError(EROFS)
649 2715ade4 Sofia Papagiannaki
650 49350be7 Giorgos Verigakis
    def utimens(self, path, times=None):
651 49350be7 Giorgos Verigakis
        """Times is a (atime, mtime) tuple. If None use current time."""
652 49350be7 Giorgos Verigakis
        return 0
653 2715ade4 Sofia Papagiannaki
654 49350be7 Giorgos Verigakis
    def write(self, path, data, offset, fh):
655 49350be7 Giorgos Verigakis
        raise FuseOSError(EROFS)
656 49350be7 Giorgos Verigakis
657 49350be7 Giorgos Verigakis
658 49350be7 Giorgos Verigakis
class LoggingMixIn:
659 49350be7 Giorgos Verigakis
    def __call__(self, op, path, *args):
660 49350be7 Giorgos Verigakis
        print '->', op, path, repr(args)
661 49350be7 Giorgos Verigakis
        ret = '[Unhandled Exception]'
662 49350be7 Giorgos Verigakis
        try:
663 49350be7 Giorgos Verigakis
            ret = getattr(self, op)(path, *args)
664 49350be7 Giorgos Verigakis
            return ret
665 49350be7 Giorgos Verigakis
        except OSError, e:
666 49350be7 Giorgos Verigakis
            ret = str(e)
667 49350be7 Giorgos Verigakis
            raise
668 49350be7 Giorgos Verigakis
        finally:
669 49350be7 Giorgos Verigakis
            print '<-', op, repr(ret)