This file is indexed.

/usr/lib/python2.7/dist-packages/llfuse/pyapi.py is in python-llfuse 0.40-2build2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
'''
pyapi.py

Copyright (C) Nikolaus Rath <Nikolaus@rath.org>

This file is part of LLFUSE (http://python-llfuse.googlecode.com).
LLFUSE can be distributed under the terms of the GNU LGPL.
'''

from __future__ import division, print_function, absolute_import

import os
import errno
import logging

log = logging.getLogger('llfuse')

def strerror(errno):
    try:
        return os.strerror(errno)
    except ValueError:
        return 'errno: %d' % errno

class RequestContext:
    '''
    Instances of this class are passed to some `Operations` methods to
    provide information about the caller of the syscall that initiated
    the request.
    '''

    __slots__ = [ 'uid', 'pid', 'gid', 'umask' ]

    def __init__(self):
        for name in self.__slots__:
            setattr(self, name, None)

class EntryAttributes:
    '''
    Instances of this class store attributes of directory entries.
    Most of the attributes correspond to the elements of the ``stat``
    C struct as returned by e.g. ``fstat`` and should be
    self-explanatory.
    
    The access, modification and creation times may be specified
    either in nanoseconds (via the *st_Xtime_ns* attributes) or in
    seconds (via the *st_Xtime* attributes). When times are specified
    both in seconds and nanoseconds, the nanosecond representation
    takes precedence. If times are represented in seconds, floating
    point numbers may be used to achieve sub-second
    resolution. Nanosecond time stamps must be integers. Note that
    using integer nanoseconds is more accurately than using float
    seconds.

    Request handlers do not need to return objects that inherit from 
    `EntryAttributes` directly as long as they provide the required
    attributes.
    '''

    # Attributes are documented in rst/data.rst
    
    __slots__ = [ 'st_ino', 'generation', 'entry_timeout',
                  'attr_timeout', 'st_mode', 'st_nlink', 'st_uid', 'st_gid',
                  'st_rdev', 'st_size', 'st_blksize', 'st_blocks',
                  'st_atime', 'st_atime_ns', 'st_mtime', 'st_mtime_ns',
                  'st_ctime', 'st_ctime_ns' ]


    def __init__(self):
        for name in self.__slots__:
            setattr(self, name, None)
      
class StatvfsData:
    '''
    Instances of this class store information about the file system.
    The attributes correspond to the elements of the ``statvfs``
    struct, see :manpage:`statvfs(2)` for details.
    
    Request handlers do not need to return objects that inherit from
    `StatvfsData` directly as long as they provide the required
    attributes.
    '''

    # Attributes are documented in rst/operations.rst
    
    __slots__ = [ 'f_bsize', 'f_frsize', 'f_blocks', 'f_bfree',
                  'f_bavail', 'f_files', 'f_ffree', 'f_favail' ]

    def __init__(self):
        for name in self.__slots__:
            setattr(self, name, None)
        
class FUSEError(Exception):
    '''
    This exception may be raised by request handlers to indicate that
    the requested operation could not be carried out. The system call
    that resulted in the request (if any) will then fail with error
    code *errno_*.
    '''

    __slots__ = [ 'errno' ]

    def __init__(self, errno_):
        super(FUSEError, self).__init__()
        self.errno = errno_

    def __str__(self):
        return strerror(self.errno)
    
class Operations(object):
    '''
    This class defines the general and request handler methods that an
    LLFUSE file system may implement. If a particular request handler
    has not been implemented, it must raise `FUSEError` with an errorcode of
    `errno.ENOSYS`.

    It is recommended that file systems are derived from this class
    and only overwrite the handlers that they actually implement. (The
    default implementations defined in this class all just raise the
    not-implemented exception).

    The only exception that request handlers are allowed to raise is
    `FUSEError`. This will cause the specified errno to be
    returned by the syscall that is being handled.

    Note that all character data (directory entry names, extended
    attribute names and values, symbolic link targets etc) are passed
    as `bytes` and must be returned as `bytes`. This applies to both
    running under Python 2.x and 3.x
    '''
    
    def init(self):
        '''Initialize operations
        
        This function will be called just before the file system
        starts handling requests. It must not raise any exceptions
        (including `FUSEError`, since this method is not handling a
        particular syscall).
        '''
        
        pass
    
    def destroy(self):
        '''Clean up operations.
        
        This method will be called when `llfuse.close` has been called
        and the file system is about to be unmounted.

        Since this handler is thus *not* run as part of the main loop,
        it is also *not* called with the global lock acquired (unless
        the caller of `llfuse.close` already holds the lock).

        This method must not raise any exceptions (including
        `FUSEError`, since this method is not handling a particular
        syscall).
        '''
        
        pass

    def lookup(self, parent_inode, name):
        '''Look up a directory entry by name and get its attributes.
    
        If the entry *name* does not exist in the directory with inode
        *parent_inode*, this method must raise `FUSEError` with an
        errno of `errno.ENOENT`. Otherwise it must return an
        `EntryAttributes` instance.

        Once an inode has been returned by `lookup`, `create`,
        `symlink`, `link`, `mknod` or `mkdir`, it must be kept by the
        file system until it receives a `forget` request for the
        inode. If `unlink` or `rmdir` requests are received prior to
        the `forget` call, they are expect to remove only the
        directory entry for the inode and defer removal of the inode
        itself until the `forget` call.

        The file system must be able to handle lookups for :file:`.`
        and :file:`..`, no matter if these entries are returned by
        `readdir` or not.
        '''
        
        raise FUSEError(errno.ENOSYS)
    
    def forget(self, inode_list):
        '''Notify about inodes being removed from the kernel cache

        *inode_list* is a list of ``(inode, nlookup)`` tuples. This
        method is called when the kernel removes the listed inodes
        from its internal caches. *nlookup* is the number of times
        that the inode has been looked up by calling either of the
        `lookup`, `create`, `symlink`, `mknod`, `link` or `mkdir`
        methods.

        The file system is expected to keep track of the number of
        times an inode has been looked up and forgotten. No request
        handlers other than `lookup` will be called for an inode with
        a lookup count of zero.

        If the lookup count reaches zero after a call to `forget`, the
        file system is expected to check if there are still directory
        entries referring to this inode and, if not, delete the inode
        itself.

        If the file system is unmounted, it will may not receive
        `forget` calls for inodes that are still cached. The `destroy`
        method may be used to clean up any remaining inodes for which
        no `forget` call has been received.
        '''
        
        pass
    
    def getattr(self, inode):
        '''Get attributes for *inode*
    
        This method should return an `EntryAttributes` instance with
        the attributes of *inode*. The
        `~EntryAttributes.entry_timeout` attribute is ignored in this
        context.
        '''
        
        raise FUSEError(errno.ENOSYS)


    def setattr(self, inode, attr):
        '''Change attributes of *inode*
        
        *attr* is an `EntryAttributes` instance with the new
        attributes. Only the attributes `~EntryAttributes.st_size`,
        `~EntryAttributes.st_mode`, `~EntryAttributes.st_uid`,
        `~EntryAttributes.st_gid`, `~EntryAttributes.st_atime` and
        `~EntryAttributes.st_mtime` are relevant. Unchanged attributes
        will have a value `None`.
        
        The method should return a new `EntryAttributes` instance
        with the updated attributes (i.e., all attributes except for
        `~EntryAttributes.entry_timeout` should be set).
        '''
        
        raise FUSEError(errno.ENOSYS)

    def readlink(self, inode):
        '''Return target of symbolic link

        The return value must have type `bytes`.
        '''
        
        raise FUSEError(errno.ENOSYS)

 
    def mknod(self, parent_inode, name, mode, rdev, ctx):
        '''Create (possibly special) file
    
        *ctx* will be a `RequestContext` instance. The method must
        return an `EntryAttributes` instance with the attributes of
        the newly created directory entry.

        Once an inode has been returned by `lookup`, `create`,
        `symlink`, `link`, `mknod` or `mkdir`, it must be kept by the
        file system until it receives a `forget` request for the
        inode. If `unlink` or `rmdir` requests are received prior to
        the `forget` call, they are expect to remove only the
        directory entry for the inode and defer removal of the inode
        itself until the `forget` call.
        '''
        
        raise FUSEError(errno.ENOSYS)

    def mkdir(self, parent_inode, name, mode, ctx):
        '''Create a directory
    
        *ctx* will be a `RequestContext` instance. The method must
        return an `EntryAttributes` instance with the attributes of
        the newly created directory entry.

        Once an inode has been returned by `lookup`, `create`,
        `symlink`, `link`, `mknod` or `mkdir`, it must be kept by the
        file system until it receives a `forget` request for the
        inode. If `unlink` or `rmdir` requests are received prior to
        the `forget` call, they are expect to remove only the
        directory entry for the inode and defer removal of the inode
        itself until the `forget` call.
        '''
        
        raise FUSEError(errno.ENOSYS)
    
    def unlink(self, parent_inode, name):
        '''Remove a (possibly special) file

        If the file system has received a `lookup`, but no `forget`
        call for this file yet, `unlink` is expected to remove only
        the directory entry and defer removal of the inode with the
        actual file contents and metadata until the `forget` call is
        received.

        Note that an unlinked file may also appear again if it gets a
        new directory entry by the `link` method.
        '''
        
        raise FUSEError(errno.ENOSYS)

    def rmdir(self, inode_parent, name):
        '''Remove a directory

        If the file system has received a `lookup`, but no `forget`
        call for this file yet, `unlink` is expected to remove only
        the directory entry and defer removal of the inode with the
        actual file contents and metadata until the `forget` call is
        received.
        '''
        
        raise FUSEError(errno.ENOSYS)

    def symlink(self, inode_parent, name, target, ctx):
        '''Create a symbolic link
        
        *ctx* will be a `RequestContext` instance. The method must
        return an `EntryAttributes` instance with the attributes of
        the newly created directory entry.

        Once an inode has been returned by `lookup`, `create`,
        `symlink`, `link`, `mknod` or `mkdir`, it must be kept by the
        file system until it receives a `forget` request for the
        inode. If `unlink` or `rmdir` requests are received prior to
        the `forget` call, they are expect to remove only the
        directory entry for the inode and defer removal of the inode
        itself until the `forget` call.
        '''
        
        raise FUSEError(errno.ENOSYS)
    
    def rename(self, inode_parent_old, name_old, inode_parent_new, name_new):
        '''Rename a directory entry

        If *name_new* already exists, it should be overwritten.
        
        If the file system has received a `lookup`, but no `forget`
        call for the file that is about to be overwritten, `rename` is
        expected to only overwrite the directory entry and defer
        removal of the old inode with the its contents and metadata
        until the `forget` call is received.
        '''
        
        raise FUSEError(errno.ENOSYS)
    
    def link(self, inode, new_parent_inode, new_name):
        '''Create a hard link.
    
        The method must return an `EntryAttributes` instance with the
        attributes of the newly created directory entry.

        Once an inode has been returned by `lookup`, `create`,
        `symlink`, `link`, `mknod` or `mkdir`, it must be kept by the
        file system until it receives a `forget` request for the
        inode. If `unlink` or `rmdir` requests are received prior to
        the `forget` call, they are expect to remove only the
        directory entry for the inode and defer removal of the inode
        itself until the `forget` call.
        '''
        
        raise FUSEError(errno.ENOSYS)
    
    def open(self, inode, flags):
        '''Open a file.
        
        *flags* will be a bitwise or of the open flags described in
        the :manpage:`open(2)` manpage and defined in the `os` module
        (with the exception of ``O_CREAT``, ``O_EXCL``, ``O_NOCTTY``
        and ``O_TRUNC``)

        This method should return an integer file handle. The file
        handle will be passed to the `read`, `write`, `flush`, `fsync`
        and `release` methods to identify the open file.
        '''
        
        raise FUSEError(errno.ENOSYS)
    
    def read(self, fh, off, size):
        '''Read *size* bytes from *fh* at position *off*
        
        This function should return exactly the number of bytes
	requested except on EOF or error, otherwise the rest of the
	data will be substituted with zeroes.
        '''
        
        raise FUSEError(errno.ENOSYS)

    def write(self, fh, off, buf):
        '''Write *buf* into *fh* at *off*
        
        This method should return the number of bytes written. If no
        error occured, this should be exactly :samp:`len(buf)`.
        '''
        
        raise FUSEError(errno.ENOSYS)
    
    def flush(self, fh):
        '''Handle close() syscall.
        
        This method is called whenever a file descriptor is closed. It
        may be called multiple times for the same open file (e.g. if
        the file handle has been duplicated).
                                                             
        If the file system implements locking, this method must clear
        all locks belonging to the file handle's owner.
        '''
        
        raise FUSEError(errno.ENOSYS)

    def release(self, fh):
        '''Release open file
        
        This method will be called when the last file descriptor of
        *fh* has been closed. Therefore it will be called exactly once
        for each `open` call.
        '''
        
        raise FUSEError(errno.ENOSYS)
    
    def fsync(self, fh, datasync):
        '''Flush buffers for open file *fh*
        
        If *datasync* is true, only the file contents should be
        flushed (in contrast to the metadata about the file).
        '''
        
        raise FUSEError(errno.ENOSYS)
    
    def opendir(self, inode):
        '''Open a directory.
        
        This method should return an integer file handle. The file
        handle will be passed to the `readdir`, `fsyncdir`
        and `releasedir` methods to identify the directory.
        '''
        
        raise FUSEError(errno.ENOSYS)
    

    def readdir(self, fh, off):
        '''Read directory entries
        
        This method should return an iterator over the contents of
        directory *fh*, starting at the entry identified by *off*.
        Directory entries must be of type `bytes`.
        
        The iterator must yield tuples of the form :samp:`({name}, {attr},
        {next_})`, where *attr* is an `EntryAttributes` instance and
        *next_* gives an offset that can be passed as *off* to start
        a successive `readdir` call at the right position.
         
        Iteration may be stopped as soon as enough elements have been
        retrieved. The method should be prepared for this case.

        If entries are added or removed during a `readdir` cycle, they
        may or may not be returned. However, they must not cause other
        entries to be skipped or returned more than once.

        :file:`.` and :file:`..` entries may be included but are not
        required.
        '''
        
        raise FUSEError(errno.ENOSYS)
    
    def releasedir(self, fh):
        '''Release open directory
        
        This method must be called exactly once for each `opendir` call.
        '''
        
        raise FUSEError(errno.ENOSYS)
    
    def fsyncdir(self, fh, datasync):  
        '''Flush buffers for open directory *fh*
        
        If *datasync* is true, only the directory contents should be
        flushed (in contrast to metadata about the directory itself).
        '''
        
        raise FUSEError(errno.ENOSYS)
        
    def statfs(self):
        '''Get file system statistics

        The method is expected to return an appropriately filled
        `StatvfsData` instance.
        '''
        
        raise FUSEError(errno.ENOSYS)

    def stacktrace(self):
        '''Asynchronous debugging
        
        This method will be called when the ``fuse_stacktrace`` extended
        attribute is set on the mountpoint. It will be called without
        holding the global lock. The default implementation logs the
        current stack trace of every running Python thread. This can be
        quite useful to debug file system deadlocks.
        '''

        import sys
        import traceback
        
        code = list()
        for threadId, frame in sys._current_frames().items():
            code.append("\n# ThreadID: %s" % threadId)
            for filename, lineno, name, line in traceback.extract_stack(frame):
                code.append('%s:%d, in %s' % (os.path.basename(filename), lineno, name))
                if line:
                    code.append("    %s" % (line.strip()))

        log.error("\n".join(code))
    
    def setxattr(self, inode, name, value):
        '''Set an extended attribute.
        
        The attribute may or may not exist already.
        '''
        
        raise FUSEError(errno.ENOSYS)
    
    def getxattr(self, inode, name):
        '''Return extended attribute value
        
        If the attribute does not exist, the method must raise
        `FUSEError` with an error code of `ENOATTR`.
        '''
        
        raise FUSEError(errno.ENOSYS)

    def listxattr(self, inode):
        '''Get list of extended attribute names'''
        
        raise FUSEError(errno.ENOSYS)
    
    def removexattr(self, inode, name):
        '''Remove extended attribute
        
        If the attribute does not exist, the method must raise
        `FUSEError` with an error code of `ENOATTR`.
        '''
        
        raise FUSEError(errno.ENOSYS)
    
    
    def access(self, inode, mode, ctx):
        '''Check if requesting process has *mode* rights on *inode*. 

        *ctx* will be a `RequestContext` instance. The method
        must return a boolean value.
        
        If the ``default_permissions`` mount option is given, this method is not
        called.
        '''
        
        raise FUSEError(errno.ENOSYS)
    
    def create(self, inode_parent, name, mode, flags, ctx):
        '''Create a file with permissions *mode* and open it with *flags*
                
        *ctx* will be a `RequestContext` instance.

        The method must return a tuple of the form *(fh, attr)*,
        where *fh* is a file handle like the one returned by `open`
        and *attr* is an `EntryAttributes` instance with the
        attributes of the newly created directory entry.

        Once an inode has been returned by `lookup`, `create`,
        `symlink`, `link`, `mknod` or `mkdir`, it must be kept by the
        file system until it receives a `forget` request for the
        inode. If `unlink` or `rmdir` requests are received prior to
        the `forget` call, they are expect to remove only the
        directory entry for the inode and defer removal of the inode
        itself until the `forget` call.
        '''
        
        raise FUSEError(errno.ENOSYS)