Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'python/src/tcf/services/filesystem.py')
-rw-r--r--python/src/tcf/services/filesystem.py1206
1 files changed, 603 insertions, 603 deletions
diff --git a/python/src/tcf/services/filesystem.py b/python/src/tcf/services/filesystem.py
index 524bea907..726b71810 100644
--- a/python/src/tcf/services/filesystem.py
+++ b/python/src/tcf/services/filesystem.py
@@ -1,603 +1,603 @@
-# *******************************************************************************
-# * Copyright (c) 2011 Wind River Systems, Inc. and others.
-# * All rights reserved. This program and the accompanying materials
-# * are made available under the terms of the Eclipse Public License v1.0
-# * which accompanies this distribution, and is available at
-# * http://www.eclipse.org/legal/epl-v10.html
-# *
-# * Contributors:
-# * Wind River Systems - initial API and implementation
-# *******************************************************************************
-
-"""
-File System service provides file transfer (and more generally file
-system access) functionality in TCF. The service design is
-derived from SSH File Transfer Protocol specifications.
-
- Request Synchronization and Reordering
-
-The protocol and implementations MUST process requests relating to
-the same file in the order in which they are received. In other
-words, if an application submits multiple requests to the server, the
-results in the responses will be the same as if it had sent the
-requests one at a time and waited for the response in each case. For
-example, the server may process non-overlapping read/write requests
-to the same file in parallel, but overlapping reads and writes cannot
-be reordered or parallelized. However, there are no ordering
-restrictions on the server for processing requests from two different
-file transfer connections. The server may interleave and parallelize
-them at will.
-
-There are no restrictions on the order in which responses to
-outstanding requests are delivered to the client, except that the
-server must ensure fairness in the sense that processing of no
-request will be indefinitely delayed even if the client is sending
-other requests so that there are multiple outstanding requests all
-the time.
-
-There is no limit on the number of outstanding (non-acknowledged)
-requests that the client may send to the server. In practice this is
-limited by the buffering available on the data stream and the queuing
-performed by the server. If the server's queues are full, it should
-not read any more data from the stream, and flow control will prevent
-the client from sending more requests.
-
- File Names
-
-This protocol represents file names as strings. File names are
-assumed to use the slash ('/') character as a directory separator.
-
-File names starting with a slash are "absolute", and are relative to
-the root of the file system. Names starting with any other character
-are relative to the user's default directory (home directory). Client
-can use 'user()' command to retrieve current user home directory.
-
-Servers SHOULD interpret a path name component ".." as referring to
-the parent directory, and "." as referring to the current directory.
-If the server implementation limits access to certain parts of the
-file system, it must be extra careful in parsing file names when
-enforcing such restrictions. There have been numerous reported
-security bugs where a ".." in a path name has allowed access outside
-the intended area.
-
-An empty path name is valid, and it refers to the user's default
-directory (usually the user's home directory).
-
-Otherwise, no syntax is defined for file names by this specification.
-Clients should not make any other assumptions however, they can
-splice path name components returned by readdir() together
-using a slash ('/') as the separator, and that will work as expected.
-"""
-
-from tcf import services
-
-# Service name.
-NAME = "FileSystem"
-
-# Flags to be used with open() method.
-
-# Open the file for reading.
-TCF_O_READ = 0x00000001
-
-# Open the file for writing. If both this and TCF_O_READ are
-# specified, the file is opened for both reading and writing.
-TCF_O_WRITE = 0x00000002
-
-# Force all writes to append data at the end of the file.
-TCF_O_APPEND = 0x00000004
-
-# If this flag is specified, then a new file will be created if one
-# does not already exist (if TCF_O_TRUNC is specified, the new file will
-# be truncated to zero length if it previously exists).
-TCF_O_CREAT = 0x00000008
-
-# Forces an existing file with the same name to be truncated to zero
-# length when creating a file by specifying TCF_O_CREAT.
-# TCF_O_CREAT MUST also be specified if this flag is used.
-TCF_O_TRUNC = 0x00000010
-
-# Causes the request to fail if the named file already exists.
-# TCF_O_CREAT MUST also be specified if this flag is used.
-TCF_O_EXCL = 0x00000020
-
-# Flags to be used together with FileAttrs.
-# The flags specify which of the fields are present. Those fields
-# for which the corresponding flag is not set are not present (not
-# included in the message).
-ATTR_SIZE = 0x00000001
-ATTR_UIDGID = 0x00000002
-ATTR_PERMISSIONS = 0x00000004
-ATTR_ACMODTIME = 0x00000008
-
-class FileAttrs(object):
- """
- FileAttrs is used both when returning file attributes from
- the server and when sending file attributes to the server. When
- sending it to the server, the flags field specifies which attributes
- are included, and the server will use default values for the
- remaining attributes (or will not modify the values of remaining
- attributes). When receiving attributes from the server, the flags
- specify which attributes are included in the returned data. The
- server normally returns all attributes it knows about.
-
- Fields:
- The 'flags' specify which of the fields are present.
- The 'size' field specifies the size of the file in bytes.
- The 'uid' and 'gid' fields contain numeric Unix-like user and group
- identifiers, respectively.
- The 'permissions' field contains a bit mask of file permissions as
- defined by posix [1].
- The 'atime' and 'mtime' contain the access and modification times of
- the files, respectively. They are represented as milliseconds from
- midnight Jan 1, 1970 in UTC.
- attributes - Additional (non-standard) attributes.
- """
- def __init__(self, flags, size, uid, gid, permissions, atime, mtime, attributes):
- self.flags = flags
- self.size = size
- self.uid = uid
- self.gid = gid
- self.permissions = permissions
- self.atime = atime
- self.mtime = mtime
- self.attributes = attributes
-
- def isFile(self):
- """
- Determines if the file system object is a file on the remote file system.
-
- @return True if and only if the object on the remote system can be considered to have "contents" that
- have the potential to be read and written as a byte stream.
- """
- if (self.flags & ATTR_PERMISSIONS) == 0: return False
- return (self.permissions & S_IFMT) == S_IFREG
-
- def isDirectory(self):
- """
- Determines if the file system object is a directory on the remote file system.
-
- @return True if and only if the object on the remote system is a directory.
- That is, it contains entries that can be interpreted as other files.
- """
- if (self.flags & ATTR_PERMISSIONS) == 0: return False
- return (self.permissions & S_IFMT) == S_IFDIR
-
-# The following flags are defined for the 'permissions' field:
-S_IFMT = 0170000 # bitmask for the file type bitfields
-S_IFSOCK = 0140000 # socket
-S_IFLNK = 0120000 # symbolic link
-S_IFREG = 0100000 # regular file
-S_IFBLK = 0060000 # block device
-S_IFDIR = 0040000 # directory
-S_IFCHR = 0020000 # character device
-S_IFIFO = 0010000 # fifo
-S_ISUID = 0004000 # set UID bit
-S_ISGID = 0002000 # set GID bit (see below)
-S_ISVTX = 0001000 # sticky bit (see below)
-S_IRWXU = 00700 # mask for file owner permissions
-S_IRUSR = 00400 # owner has read permission
-S_IWUSR = 00200 # owner has write permission
-S_IXUSR = 00100 # owner has execute permission
-S_IRWXG = 00070 # mask for group permissions
-S_IRGRP = 00040 # group has read permission
-S_IWGRP = 00020 # group has write permission
-S_IXGRP = 00010 # group has execute permission
-S_IRWXO = 00007 # mask for permissions for others (not in group)
-S_IROTH = 00004 # others have read permission
-S_IWOTH = 00002 # others have write permission
-S_IXOTH = 00001 # others have execute permission
-
-class DirEntry(object):
- """
- Directory entry.
- Fields:
- 'filename' is a file name being returned. It is a relative name within
- the directory, without any path components
- 'longname' is an expanded format for the file name, similar to what
- is returned by "ls -l" on Unix systems.
- The format of the 'longname' field is unspecified by this protocol.
- It MUST be suitable for use in the output of a directory listing
- command (in fact, the recommended operation for a directory listing
- command is to simply display this data). However, clients SHOULD NOT
- attempt to parse the longname field for file attributes they SHOULD
- use the attrs field instead.
- 'attrs' is the attributes of the file.
- """
- def __init__(self, filename, longname, attrs):
- self.filename = filename
- self.longname = longname
- self.attrs = attrs
-
-class FileHandle(object):
- def __init__(self, service, id):
- self.service = service
- self.id = id
-
- def getService(self):
- return self.service
-
- def __str__(self):
- return "[File Handle '%s'" % self.id
-
-# Service specific error codes.
-
-# Indicates end-of-file condition for read() it means that no
-# more data is available in the file, and for readdir() it
-# indicates that no more files are contained in the directory.
-STATUS_EOF = 0x10001
-
-# This code is returned when a reference is made to a file which
-# should exist but doesn't.
-STATUS_NO_SUCH_FILE = 0x10002
-
-# is returned when the authenticated user does not have sufficient
-# permissions to perform the operation.
-STATUS_PERMISSION_DENIED = 0x10003
-
-class FileSystemException(IOError):
- """
- The class to represent File System error reports.
- """
- def __init__(self, message_or_exception):
- if isinstance(message_or_exception, str):
- super(FileSystemException, self).__init__(message_or_exception)
- elif isinstance(message_or_exception, Exception):
- self.caused_by = message_or_exception
- def getStatus(self):
- """
- Get error code. The code can be standard TCF error code or
- one of service specific codes, see STATUS_*.
- @return error code.
- """
- raise NotImplementedError("Abstract methods")
-
-class FileSystemService(services.Service):
- def getName(self):
- return NAME
-
- def open(self, file_name, flags, attrs, done):
- """
- Open or create a file on a remote system.
-
- @param file_name specifies the file name. See 'File Names' for more information.
- @param flags is a bit mask of TCF_O_* flags.
- @param attrs specifies the initial attributes for the file.
- Default values will be used for those attributes that are not specified.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def close(self, handle, done):
- """
- Close a file on a remote system.
-
- @param handle is a handle previously returned in the response to
- open() or opendir().
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def read(self, handle, offset, len, done):
- """
- Read bytes from an open file.
- In response to this request, the server will read as many bytes as it
- can from the file (up to 'len'), and return them in a byte array.
- If an error occurs or EOF is encountered, the server may return
- fewer bytes then requested. Call back method doneRead() argument 'error'
- will be not None in case of error, and argument 'eof' will be
- True in case of EOF. For normal disk files, it is guaranteed
- that this will read the specified number of bytes, or up to end of file
- or error. For e.g. device files this may return fewer bytes than requested.
-
- @param handle is an open file handle returned by open().
- @param offset is the offset (in bytes) relative
- to the beginning of the file from where to start reading.
- If offset < 0 then reading starts from current position in the file.
- @param len is the maximum number of bytes to read.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def write(self, handle, offset, data, data_pos, data_size, done):
- """
- Write bytes into an open file.
- The write will extend the file if writing beyond the end of the file.
- It is legal to write way beyond the end of the file the semantics
- are to write zeroes from the end of the file to the specified offset
- and then the data.
-
- @param handle is an open file handle returned by open().
- @param offset is the offset (in bytes) relative
- to the beginning of the file from where to start writing.
- If offset < 0 then writing starts from current position in the file.
- @param data is byte array that contains data for writing.
- @param data_pos if offset in 'data' of first byte to write.
- @param data_size is the number of bytes to write.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def stat(self, path, done):
- """
- Retrieve file attributes.
-
- @param path - specifies the file system object for which
- status is to be returned.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def lstat(self, path, done):
- """
- Retrieve file attributes.
- Unlike 'stat()', 'lstat()' does not follow symbolic links.
-
- @param path - specifies the file system object for which
- status is to be returned.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def fstat(self, handle, done):
- """
- Retrieve file attributes for an open file (identified by the file handle).
-
- @param handle is a file handle returned by 'open()'.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def setstat(self, path, attrs, done):
- """
- Set file attributes.
- This request is used for operations such as changing the ownership,
- permissions or access times, as well as for truncating a file.
- An error will be returned if the specified file system object does
- not exist or the user does not have sufficient rights to modify the
- specified attributes.
-
- @param path specifies the file system object (e.g. file or directory)
- whose attributes are to be modified.
- @param attrs specifies the modifications to be made to file attributes.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def fsetstat(self, handle, attrs, done):
- """
- Set file attributes for an open file (identified by the file handle).
- This request is used for operations such as changing the ownership,
- permissions or access times, as well as for truncating a file.
-
- @param handle is a file handle returned by 'open()'.
- @param attrs specifies the modifications to be made to file attributes.
- @param done is call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def opendir(self, path, done):
- """
- The opendir() command opens a directory for reading.
- Once the directory has been successfully opened, files (and
- directories) contained in it can be listed using readdir() requests.
- When the client no longer wishes to read more names from the
- directory, it SHOULD call close() for the handle. The handle
- should be closed regardless of whether an error has occurred or not.
-
- @param path - name of the directory to be listed (without any trailing slash).
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def readdir(self, handle, done):
- """
- The files in a directory can be listed using the opendir() and
- readdir() requests. Each readdir() request returns one
- or more file names with full file attributes for each file. The
- client should call readdir() repeatedly until it has found the
- file it is looking for or until the server responds with a
- message indicating an error or end of file. The client should then
- close the handle using the close() request.
- Note: directory entries "." and ".." are NOT included into readdir()
- response.
- @param handle - file handle created by opendir()
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def mkdir(self, path, attrs, done):
- """
- Create a directory on the server.
-
- @param path - specifies the directory to be created.
- @param attrs - new directory attributes.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def rmdir(self, path, done):
- """
- Remove a directory.
- An error will be returned if no directory
- with the specified path exists, or if the specified directory is not
- empty, or if the path specified a file system object other than a
- directory.
-
- @param path - specifies the directory to be removed.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def roots(self, done):
- """
- Retrieve file system roots - top level file system objects.
- UNIX file system can report just one root with path "/". Other types of systems
- can have more the one root. For example, Windows server can return multiple roots:
- one per disc (e.g. "/C:/", "/D:/", etc.). Note: even Windows implementation of
- the service must use forward slash as directory separator, and must start
- absolute path with "/". Server should implement proper translation of
- protocol file names to OS native names and back.
-
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def remove(self, file_name, done):
- """
- Remove a file or symbolic link.
- This request cannot be used to remove directories.
-
- @param file_name is the name of the file to be removed.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def realpath(self, path, done):
- """
- Canonicalize any given path name to an absolute path.
- This is useful for converting path names containing ".." components or
- relative pathnames without a leading slash into absolute paths.
-
- @param path specifies the path name to be canonicalized.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def rename(self, old_path, new_path, done):
- """
- Rename a file.
- It is an error if there already exists a file
- with the name specified by 'new_path'. The server may also fail rename
- requests in other situations, for example if 'old_path' and 'new_path'
- point to different file systems on the server.
-
- @param old_path is the name of an existing file or directory.
- @param new_path is the new name for the file or directory.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def readlink(self, path, done):
- """
- Read the target of a symbolic link.
-
- @param path specifies the path name of the symbolic link to be read.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def symlink(self, link_path, target_path, done):
- """
- Create a symbolic link on the server.
-
- @param link_path specifies the path name of the symbolic link to be created.
- @param target_path specifies the target of the symbolic link.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def copy(self, src_path, dst_path, copy_permissions, copy_ownership, done):
- """
- Copy a file on remote system.
-
- @param src_path specifies the path name of the file to be copied.
- @param dst_path specifies destination file name.
- @param copy_permissions - if True then copy source file permissions.
- @param copy_ownership - if True then copy source file UID and GID.
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
- def user(self, done):
- """
- Retrieve information about user account, which is used by server
- to access file system on behalf of the client.
-
- @param done - result call back object.
- @return pending command handle.
- """
- raise NotImplementedError("Abstract methods")
-
-class DoneOpen(object):
- def doneOpen(self, token, error, handle):
- pass
-
-class DoneClose(object):
- def doneClose(self, token, error):
- pass
-
-class DoneRead(object):
- def doneRead(self, token, error, data, eof):
- pass
-
-class DoneWrite(object):
- def doneWrite(self, token, error):
- pass
-
-class DoneStat(object):
- def doneStat(self, token, error, attrs):
- pass
-
-class DoneSetStat(object):
- def doneSetStat(self, token, error):
- pass
-
-class DoneReadDir(object):
- def doneReadDir(self, token, error, entries, eof):
- pass
-
-class DoneMkDir(object):
- def doneMkDir(self, token, error):
- pass
-
-class DoneRemove(object):
- def doneRemove(self, token, error):
- pass
-
-class DoneRoots(object):
- def doneRoots(self, token, error, entries):
- pass
-
-class DoneRealPath(object):
- def doneRealPath(self, token, error, path):
- pass
-
-class DoneRename(object):
- def doneRename(self, token, error):
- pass
-
-class DoneReadLink(object):
- def doneReadLink(self, token, error, path):
- pass
-
-class DoneSymLink(object):
- def doneSymLink(self, token, error):
- pass
-
-class DoneCopy(object):
- def doneCopy(self, token, error):
- pass
-
-class DoneUser(object):
- def doneUser(self, token, error, real_uid, effective_uid, real_gid, effective_gid, home):
- pass
+# *******************************************************************************
+# * Copyright (c) 2011 Wind River Systems, Inc. and others.
+# * All rights reserved. This program and the accompanying materials
+# * are made available under the terms of the Eclipse Public License v1.0
+# * which accompanies this distribution, and is available at
+# * http://www.eclipse.org/legal/epl-v10.html
+# *
+# * Contributors:
+# * Wind River Systems - initial API and implementation
+# *******************************************************************************
+
+"""
+File System service provides file transfer (and more generally file
+system access) functionality in TCF. The service design is
+derived from SSH File Transfer Protocol specifications.
+
+ Request Synchronization and Reordering
+
+The protocol and implementations MUST process requests relating to
+the same file in the order in which they are received. In other
+words, if an application submits multiple requests to the server, the
+results in the responses will be the same as if it had sent the
+requests one at a time and waited for the response in each case. For
+example, the server may process non-overlapping read/write requests
+to the same file in parallel, but overlapping reads and writes cannot
+be reordered or parallelized. However, there are no ordering
+restrictions on the server for processing requests from two different
+file transfer connections. The server may interleave and parallelize
+them at will.
+
+There are no restrictions on the order in which responses to
+outstanding requests are delivered to the client, except that the
+server must ensure fairness in the sense that processing of no
+request will be indefinitely delayed even if the client is sending
+other requests so that there are multiple outstanding requests all
+the time.
+
+There is no limit on the number of outstanding (non-acknowledged)
+requests that the client may send to the server. In practice this is
+limited by the buffering available on the data stream and the queuing
+performed by the server. If the server's queues are full, it should
+not read any more data from the stream, and flow control will prevent
+the client from sending more requests.
+
+ File Names
+
+This protocol represents file names as strings. File names are
+assumed to use the slash ('/') character as a directory separator.
+
+File names starting with a slash are "absolute", and are relative to
+the root of the file system. Names starting with any other character
+are relative to the user's default directory (home directory). Client
+can use 'user()' command to retrieve current user home directory.
+
+Servers SHOULD interpret a path name component ".." as referring to
+the parent directory, and "." as referring to the current directory.
+If the server implementation limits access to certain parts of the
+file system, it must be extra careful in parsing file names when
+enforcing such restrictions. There have been numerous reported
+security bugs where a ".." in a path name has allowed access outside
+the intended area.
+
+An empty path name is valid, and it refers to the user's default
+directory (usually the user's home directory).
+
+Otherwise, no syntax is defined for file names by this specification.
+Clients should not make any other assumptions however, they can
+splice path name components returned by readdir() together
+using a slash ('/') as the separator, and that will work as expected.
+"""
+
+from tcf import services
+
+# Service name.
+NAME = "FileSystem"
+
+# Flags to be used with open() method.
+
+# Open the file for reading.
+TCF_O_READ = 0x00000001
+
+# Open the file for writing. If both this and TCF_O_READ are
+# specified, the file is opened for both reading and writing.
+TCF_O_WRITE = 0x00000002
+
+# Force all writes to append data at the end of the file.
+TCF_O_APPEND = 0x00000004
+
+# If this flag is specified, then a new file will be created if one
+# does not already exist (if TCF_O_TRUNC is specified, the new file will
+# be truncated to zero length if it previously exists).
+TCF_O_CREAT = 0x00000008
+
+# Forces an existing file with the same name to be truncated to zero
+# length when creating a file by specifying TCF_O_CREAT.
+# TCF_O_CREAT MUST also be specified if this flag is used.
+TCF_O_TRUNC = 0x00000010
+
+# Causes the request to fail if the named file already exists.
+# TCF_O_CREAT MUST also be specified if this flag is used.
+TCF_O_EXCL = 0x00000020
+
+# Flags to be used together with FileAttrs.
+# The flags specify which of the fields are present. Those fields
+# for which the corresponding flag is not set are not present (not
+# included in the message).
+ATTR_SIZE = 0x00000001
+ATTR_UIDGID = 0x00000002
+ATTR_PERMISSIONS = 0x00000004
+ATTR_ACMODTIME = 0x00000008
+
+class FileAttrs(object):
+ """
+ FileAttrs is used both when returning file attributes from
+ the server and when sending file attributes to the server. When
+ sending it to the server, the flags field specifies which attributes
+ are included, and the server will use default values for the
+ remaining attributes (or will not modify the values of remaining
+ attributes). When receiving attributes from the server, the flags
+ specify which attributes are included in the returned data. The
+ server normally returns all attributes it knows about.
+
+ Fields:
+ The 'flags' specify which of the fields are present.
+ The 'size' field specifies the size of the file in bytes.
+ The 'uid' and 'gid' fields contain numeric Unix-like user and group
+ identifiers, respectively.
+ The 'permissions' field contains a bit mask of file permissions as
+ defined by posix [1].
+ The 'atime' and 'mtime' contain the access and modification times of
+ the files, respectively. They are represented as milliseconds from
+ midnight Jan 1, 1970 in UTC.
+ attributes - Additional (non-standard) attributes.
+ """
+ def __init__(self, flags, size, uid, gid, permissions, atime, mtime, attributes):
+ self.flags = flags
+ self.size = size
+ self.uid = uid
+ self.gid = gid
+ self.permissions = permissions
+ self.atime = atime
+ self.mtime = mtime
+ self.attributes = attributes
+
+ def isFile(self):
+ """
+ Determines if the file system object is a file on the remote file system.
+
+ @return True if and only if the object on the remote system can be considered to have "contents" that
+ have the potential to be read and written as a byte stream.
+ """
+ if (self.flags & ATTR_PERMISSIONS) == 0: return False
+ return (self.permissions & S_IFMT) == S_IFREG
+
+ def isDirectory(self):
+ """
+ Determines if the file system object is a directory on the remote file system.
+
+ @return True if and only if the object on the remote system is a directory.
+ That is, it contains entries that can be interpreted as other files.
+ """
+ if (self.flags & ATTR_PERMISSIONS) == 0: return False
+ return (self.permissions & S_IFMT) == S_IFDIR
+
+# The following flags are defined for the 'permissions' field:
+S_IFMT = 0170000 # bitmask for the file type bitfields
+S_IFSOCK = 0140000 # socket
+S_IFLNK = 0120000 # symbolic link
+S_IFREG = 0100000 # regular file
+S_IFBLK = 0060000 # block device
+S_IFDIR = 0040000 # directory
+S_IFCHR = 0020000 # character device
+S_IFIFO = 0010000 # fifo
+S_ISUID = 0004000 # set UID bit
+S_ISGID = 0002000 # set GID bit (see below)
+S_ISVTX = 0001000 # sticky bit (see below)
+S_IRWXU = 00700 # mask for file owner permissions
+S_IRUSR = 00400 # owner has read permission
+S_IWUSR = 00200 # owner has write permission
+S_IXUSR = 00100 # owner has execute permission
+S_IRWXG = 00070 # mask for group permissions
+S_IRGRP = 00040 # group has read permission
+S_IWGRP = 00020 # group has write permission
+S_IXGRP = 00010 # group has execute permission
+S_IRWXO = 00007 # mask for permissions for others (not in group)
+S_IROTH = 00004 # others have read permission
+S_IWOTH = 00002 # others have write permission
+S_IXOTH = 00001 # others have execute permission
+
+class DirEntry(object):
+ """
+ Directory entry.
+ Fields:
+ 'filename' is a file name being returned. It is a relative name within
+ the directory, without any path components
+ 'longname' is an expanded format for the file name, similar to what
+ is returned by "ls -l" on Unix systems.
+ The format of the 'longname' field is unspecified by this protocol.
+ It MUST be suitable for use in the output of a directory listing
+ command (in fact, the recommended operation for a directory listing
+ command is to simply display this data). However, clients SHOULD NOT
+ attempt to parse the longname field for file attributes they SHOULD
+ use the attrs field instead.
+ 'attrs' is the attributes of the file.
+ """
+ def __init__(self, filename, longname, attrs):
+ self.filename = filename
+ self.longname = longname
+ self.attrs = attrs
+
+class FileHandle(object):
+ def __init__(self, service, id):
+ self.service = service
+ self.id = id
+
+ def getService(self):
+ return self.service
+
+ def __str__(self):
+ return "[File Handle '%s'" % self.id
+
+# Service specific error codes.
+
+# Indicates end-of-file condition for read() it means that no
+# more data is available in the file, and for readdir() it
+# indicates that no more files are contained in the directory.
+STATUS_EOF = 0x10001
+
+# This code is returned when a reference is made to a file which
+# should exist but doesn't.
+STATUS_NO_SUCH_FILE = 0x10002
+
+# is returned when the authenticated user does not have sufficient
+# permissions to perform the operation.
+STATUS_PERMISSION_DENIED = 0x10003
+
+class FileSystemException(IOError):
+ """
+ The class to represent File System error reports.
+ """
+ def __init__(self, message_or_exception):
+ if isinstance(message_or_exception, str):
+ super(FileSystemException, self).__init__(message_or_exception)
+ elif isinstance(message_or_exception, Exception):
+ self.caused_by = message_or_exception
+ def getStatus(self):
+ """
+ Get error code. The code can be standard TCF error code or
+ one of service specific codes, see STATUS_*.
+ @return error code.
+ """
+ raise NotImplementedError("Abstract methods")
+
+class FileSystemService(services.Service):
+ def getName(self):
+ return NAME
+
+ def open(self, file_name, flags, attrs, done):
+ """
+ Open or create a file on a remote system.
+
+ @param file_name specifies the file name. See 'File Names' for more information.
+ @param flags is a bit mask of TCF_O_* flags.
+ @param attrs specifies the initial attributes for the file.
+ Default values will be used for those attributes that are not specified.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def close(self, handle, done):
+ """
+ Close a file on a remote system.
+
+ @param handle is a handle previously returned in the response to
+ open() or opendir().
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def read(self, handle, offset, len, done):
+ """
+ Read bytes from an open file.
+ In response to this request, the server will read as many bytes as it
+ can from the file (up to 'len'), and return them in a byte array.
+ If an error occurs or EOF is encountered, the server may return
+ fewer bytes then requested. Call back method doneRead() argument 'error'
+ will be not None in case of error, and argument 'eof' will be
+ True in case of EOF. For normal disk files, it is guaranteed
+ that this will read the specified number of bytes, or up to end of file
+ or error. For e.g. device files this may return fewer bytes than requested.
+
+ @param handle is an open file handle returned by open().
+ @param offset is the offset (in bytes) relative
+ to the beginning of the file from where to start reading.
+ If offset < 0 then reading starts from current position in the file.
+ @param len is the maximum number of bytes to read.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def write(self, handle, offset, data, data_pos, data_size, done):
+ """
+ Write bytes into an open file.
+ The write will extend the file if writing beyond the end of the file.
+ It is legal to write way beyond the end of the file the semantics
+ are to write zeroes from the end of the file to the specified offset
+ and then the data.
+
+ @param handle is an open file handle returned by open().
+ @param offset is the offset (in bytes) relative
+ to the beginning of the file from where to start writing.
+ If offset < 0 then writing starts from current position in the file.
+ @param data is byte array that contains data for writing.
+ @param data_pos if offset in 'data' of first byte to write.
+ @param data_size is the number of bytes to write.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def stat(self, path, done):
+ """
+ Retrieve file attributes.
+
+ @param path - specifies the file system object for which
+ status is to be returned.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def lstat(self, path, done):
+ """
+ Retrieve file attributes.
+ Unlike 'stat()', 'lstat()' does not follow symbolic links.
+
+ @param path - specifies the file system object for which
+ status is to be returned.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def fstat(self, handle, done):
+ """
+ Retrieve file attributes for an open file (identified by the file handle).
+
+ @param handle is a file handle returned by 'open()'.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def setstat(self, path, attrs, done):
+ """
+ Set file attributes.
+ This request is used for operations such as changing the ownership,
+ permissions or access times, as well as for truncating a file.
+ An error will be returned if the specified file system object does
+ not exist or the user does not have sufficient rights to modify the
+ specified attributes.
+
+ @param path specifies the file system object (e.g. file or directory)
+ whose attributes are to be modified.
+ @param attrs specifies the modifications to be made to file attributes.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def fsetstat(self, handle, attrs, done):
+ """
+ Set file attributes for an open file (identified by the file handle).
+ This request is used for operations such as changing the ownership,
+ permissions or access times, as well as for truncating a file.
+
+ @param handle is a file handle returned by 'open()'.
+ @param attrs specifies the modifications to be made to file attributes.
+ @param done is call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def opendir(self, path, done):
+ """
+ The opendir() command opens a directory for reading.
+ Once the directory has been successfully opened, files (and
+ directories) contained in it can be listed using readdir() requests.
+ When the client no longer wishes to read more names from the
+ directory, it SHOULD call close() for the handle. The handle
+ should be closed regardless of whether an error has occurred or not.
+
+ @param path - name of the directory to be listed (without any trailing slash).
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def readdir(self, handle, done):
+ """
+ The files in a directory can be listed using the opendir() and
+ readdir() requests. Each readdir() request returns one
+ or more file names with full file attributes for each file. The
+ client should call readdir() repeatedly until it has found the
+ file it is looking for or until the server responds with a
+ message indicating an error or end of file. The client should then
+ close the handle using the close() request.
+ Note: directory entries "." and ".." are NOT included into readdir()
+ response.
+ @param handle - file handle created by opendir()
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def mkdir(self, path, attrs, done):
+ """
+ Create a directory on the server.
+
+ @param path - specifies the directory to be created.
+ @param attrs - new directory attributes.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def rmdir(self, path, done):
+ """
+ Remove a directory.
+ An error will be returned if no directory
+ with the specified path exists, or if the specified directory is not
+ empty, or if the path specified a file system object other than a
+ directory.
+
+ @param path - specifies the directory to be removed.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def roots(self, done):
+ """
+ Retrieve file system roots - top level file system objects.
+ UNIX file system can report just one root with path "/". Other types of systems
+ can have more the one root. For example, Windows server can return multiple roots:
+ one per disc (e.g. "/C:/", "/D:/", etc.). Note: even Windows implementation of
+ the service must use forward slash as directory separator, and must start
+ absolute path with "/". Server should implement proper translation of
+ protocol file names to OS native names and back.
+
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def remove(self, file_name, done):
+ """
+ Remove a file or symbolic link.
+ This request cannot be used to remove directories.
+
+ @param file_name is the name of the file to be removed.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def realpath(self, path, done):
+ """
+ Canonicalize any given path name to an absolute path.
+ This is useful for converting path names containing ".." components or
+ relative pathnames without a leading slash into absolute paths.
+
+ @param path specifies the path name to be canonicalized.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def rename(self, old_path, new_path, done):
+ """
+ Rename a file.
+ It is an error if there already exists a file
+ with the name specified by 'new_path'. The server may also fail rename
+ requests in other situations, for example if 'old_path' and 'new_path'
+ point to different file systems on the server.
+
+ @param old_path is the name of an existing file or directory.
+ @param new_path is the new name for the file or directory.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def readlink(self, path, done):
+ """
+ Read the target of a symbolic link.
+
+ @param path specifies the path name of the symbolic link to be read.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def symlink(self, link_path, target_path, done):
+ """
+ Create a symbolic link on the server.
+
+ @param link_path specifies the path name of the symbolic link to be created.
+ @param target_path specifies the target of the symbolic link.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def copy(self, src_path, dst_path, copy_permissions, copy_ownership, done):
+ """
+ Copy a file on remote system.
+
+ @param src_path specifies the path name of the file to be copied.
+ @param dst_path specifies destination file name.
+ @param copy_permissions - if True then copy source file permissions.
+ @param copy_ownership - if True then copy source file UID and GID.
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+ def user(self, done):
+ """
+ Retrieve information about user account, which is used by server
+ to access file system on behalf of the client.
+
+ @param done - result call back object.
+ @return pending command handle.
+ """
+ raise NotImplementedError("Abstract methods")
+
+class DoneOpen(object):
+ def doneOpen(self, token, error, handle):
+ pass
+
+class DoneClose(object):
+ def doneClose(self, token, error):
+ pass
+
+class DoneRead(object):
+ def doneRead(self, token, error, data, eof):
+ pass
+
+class DoneWrite(object):
+ def doneWrite(self, token, error):
+ pass
+
+class DoneStat(object):
+ def doneStat(self, token, error, attrs):
+ pass
+
+class DoneSetStat(object):
+ def doneSetStat(self, token, error):
+ pass
+
+class DoneReadDir(object):
+ def doneReadDir(self, token, error, entries, eof):
+ pass
+
+class DoneMkDir(object):
+ def doneMkDir(self, token, error):
+ pass
+
+class DoneRemove(object):
+ def doneRemove(self, token, error):
+ pass
+
+class DoneRoots(object):
+ def doneRoots(self, token, error, entries):
+ pass
+
+class DoneRealPath(object):
+ def doneRealPath(self, token, error, path):
+ pass
+
+class DoneRename(object):
+ def doneRename(self, token, error):
+ pass
+
+class DoneReadLink(object):
+ def doneReadLink(self, token, error, path):
+ pass
+
+class DoneSymLink(object):
+ def doneSymLink(self, token, error):
+ pass
+
+class DoneCopy(object):
+ def doneCopy(self, token, error):
+ pass
+
+class DoneUser(object):
+ def doneUser(self, token, error, real_uid, effective_uid, real_gid, effective_gid, home):
+ pass

Back to the top