-
- def getattr(self, path):
- """
- - st_mode (protection bits)
- - st_ino (inode number)
- - st_dev (device)
- - st_nlink (number of hard links)
- - st_uid (user ID of owner)
- - st_gid (group ID of owner)
- - st_size (size of file, in bytes)
- - st_atime (time of most recent access)
- - st_mtime (time of most recent content modification)
- - st_ctime (platform dependent; time of most recent metadata change on Unix,
- or the time of creation on Windows).
- """
-
- syslog(LOG_DEBUG, "*** getattr: " + path)
-
- depth = getDepth(path)
- parts = getParts(path)
-
- st = MyStat()
- # / is a directory
- if path == '/':
- st.st_mode = stat.S_IFDIR | 0755
- st.st_nlink = 2
- # /foo is a directory if foo is a machine - otherwise it doesn't exist
- elif depth == 1:
- if parts[-1] in self.getMachines():
- st.st_mode = stat.S_IFDIR | 0755
- st.st_nlink = 2
- # Homedirs should be owned by the user whose homedir it is
- st.st_uid = st.st_gid = self.getUid(parts[0])
- else:
- return -errno.ENOENT
- # Catch the .k5login file, because it's a special case
- elif depth == 2 and parts[-1] == '.k5login':
- st.st_mode = stat.S_IFREG | 0444
- st.st_nlink = 1
- st.st_size = len(self.getK5login(parts[0]))
- # The .k5login file should be owned by the user whose homedir it is
- st.st_uid = st.st_gid = self.getUid(parts[0])
- # For anything else, we get the mirror path and call out to the OS
- else:
- stats = list(os.lstat(self.mirrorPath(path)))
- # Shadow the UID and GID from the original homedir
- stats[4:6] = [self.getUid(parts[0])] * 2
- return tuple(stats)
- return st.toTuple()
-
- # This call isn't actually used in the version of Fuse on console, but we
- # wanted to leave it implemented to ease the transition in the future
- def readdir(self, path, offset):
- """Return a generator with the listing for a directory
- """
- syslog(LOG_DEBUG, '*** readdir %s %s' % (path, offset))
- for (value, zero) in self.getdir(path):
- yield fuse.Direntry(value)
-
- def getdir(self, path):
- """Return a list of tuples of the form (item, 0) with the contents of
- the directory path
-
- Fuse doesn't add '.' or '..' on its own, so we have to
- """
- syslog(LOG_DEBUG, '*** getdir %s' % path)
-
- # '/' contains a directory for each machine
- if path == '/':
- contents = self.getMachines()
- # The directory for each machine contains the same files as the realpath
- # but also the .k5login
- #
- # The list is converted to a set so that we can handle the case where
- # there is already a .k5login in the realpath gracefully
- elif getDepth(path) == 1:
- contents = set(os.listdir(self.mirrorPath(path)) + ['.k5login'])
- # If it's not the root of the homedir, just pass the call onto the OS
- # for realpath
- else:
- contents = os.listdir(self.mirrorPath(path))
- # Format the list the way that Fuse wants it - and don't forget to add
- # '.' and '..'
- return [(i, 0) for i in (list(contents) + ['.', '..'])]
-
- def read(self, path, length, offset):
- """Read length bytes starting at offset of path. In most cases, this
- just gets passed on to the OS
- """
- syslog(LOG_DEBUG, '*** read %s %s %s' % (path, length, offset))
-
- parts = getParts(path)
-
- # If the depth is less than 2, then either it's a directory or the file
- # doesn't exist
- # (realistically this doesn't appear to ever happen)
- if getDepth(path) < 2:
- return -errno.ENOENT
- # If we're asking for a real .k5login file, then create it and return
- # the snippet requested
- elif parts[1:] == ['.k5login']:
- if parts[0] not in self.getMachines():
- return -errno.ENOENT
- else:
- return self.getK5login(parts[0])[offset:length + offset]
- # Otherwise, pass the call onto the OS
- # (note that the file will get closed when this call returns and the
- # file descriptor goes out of scope)
- else:
- fname = self.mirrorPath(path)
- if not os.path.isfile(fname):
- return -errno.ENOENT
- else:
- f = open(fname)
- f.seek(offset)
- return f.read(length)
-
- def readlink(self, path):
- syslog(LOG_DEBUG, '*** readlink %s' % path)
-
- # There aren't any symlinks here
- if getDepth(path) < 2:
- return -errno.ENOENT
- # But there might be here
- else:
- return os.readlink(self.mirrorPath(path))