diff options
Diffstat (limited to 'plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/services/IFileSystem.java')
-rw-r--r-- | plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/services/IFileSystem.java | 666 |
1 files changed, 666 insertions, 0 deletions
diff --git a/plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/services/IFileSystem.java b/plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/services/IFileSystem.java new file mode 100644 index 000000000..9e254bebb --- /dev/null +++ b/plugins/org.eclipse.tcf.core/src/org/eclipse/tcf/services/IFileSystem.java @@ -0,0 +1,666 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 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 + *******************************************************************************/ +package org.eclipse.tm.tcf.services; + +import java.io.IOException; +import java.util.Map; + +import org.eclipse.tm.tcf.protocol.IService; +import org.eclipse.tm.tcf.protocol.IToken; + + +/** + * 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. + */ +public interface IFileSystem extends IService { + + /** + * Service name. + */ + static final String NAME = "FileSystem"; + + /** + * Flags to be used with open() method. + */ + static final int + + /** + * 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). + */ + static final int + ATTR_SIZE = 0x00000001, + ATTR_UIDGID = 0x00000002, + ATTR_PERMISSIONS = 0x00000004, + ATTR_ACMODTIME = 0x00000008; + + /** + * 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. + */ + final static class FileAttrs { + + /** + * The `flags' specify which of the fields are present. + */ + public final int flags; + + /** + * The `size' field specifies the size of the file in bytes. + */ + public final long size; + + /** + * The `uid' and `gid' fields contain numeric Unix-like user and group + * identifiers, respectively. + */ + public final int uid; + public final int gid; + + /** + * The `permissions' field contains a bit mask of file permissions as + * defined by posix [1]. + */ + public final int permissions; + + /** + * 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. + */ + public final long atime; + public final long mtime; + + /** + * Additional (non-standard) attributes. + */ + public final Map<String,Object> attributes; + + public FileAttrs(int flags, long size, int uid, int gid, + int permissions, long atime, long mtime, Map<String,Object> attributes) { + this.flags = flags; + this.size = size; + this.uid = uid; + this.gid = gid; + this.permissions = permissions; + this.atime = atime; + this.mtime = mtime; + this.attributes = attributes; + } + + /** + * 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. + */ + public boolean isFile() { + if ((flags & ATTR_PERMISSIONS) == 0) return false; + return (permissions & S_IFMT) == S_IFREG; + } + + /** + * 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. + */ + public boolean isDirectory() { + if ((flags & ATTR_PERMISSIONS) == 0) return false; + return (permissions & S_IFMT) == S_IFDIR; + } + } + + /** + * The following flags are defined for the 'permissions' field: + */ + static final int + 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 + + final static class DirEntry { + /** + * `filename' is a file name being returned. It is a relative name within + * the directory, without any path components; + */ + public final String filename; + + /** + * `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. + */ + public final String longname; + + /** + * `attrs' is the attributes of the file. + */ + public final FileAttrs attrs; + + public DirEntry(String filename, String longname, FileAttrs attrs) { + this.filename = filename; + this.longname = longname; + this.attrs = attrs; + } + } + + /** + * Opaque representation of open file handle. + * Note: open file handle can be used only with service instance that + * created the handle. + */ + interface IFileHandle { + IFileSystem getService(); + } + + /** + * Service specific error codes. + */ + static final int + + /** + * 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; + + /** + * The class to represent File System error reports. + */ + @SuppressWarnings("serial") + abstract static class FileSystemException extends IOException { + + protected FileSystemException(String message) { + super(message); + } + + protected FileSystemException(Exception x) { + super(x.getMessage()); + initCause(x); + } + + /** + * Get error code. The code can be standard TCF error code or + * one of service specific codes, see STATUS_*. + * @return error code. + */ + public abstract int getStatus(); + } + + /** + * 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. + */ + IToken open(String file_name, int flags, FileAttrs attrs, DoneOpen done); + + interface DoneOpen { + void doneOpen(IToken token, FileSystemException error, IFileHandle handle); + } + + /** + * 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. + */ + IToken close(IFileHandle handle, DoneClose done); + + interface DoneClose { + void doneClose(IToken token, FileSystemException error); + } + + /** + * 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 null 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. + */ + IToken read(IFileHandle handle, long offset, int len, DoneRead done); + + interface DoneRead { + void doneRead(IToken token, FileSystemException error, byte[] data, boolean eof); + } + + /** + * 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. + */ + IToken write(IFileHandle handle, long offset, + byte[] data, int data_pos, int data_size, DoneWrite done); + + interface DoneWrite { + void doneWrite(IToken token, FileSystemException error); + } + + /** + * 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. + */ + IToken stat(String path, DoneStat 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. + */ + IToken lstat(String path, DoneStat 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. + */ + IToken fstat(IFileHandle handle, DoneStat done); + + interface DoneStat { + void doneStat(IToken token, FileSystemException error, FileAttrs attrs); + } + + /** + * 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. + */ + IToken setstat(String path, FileAttrs attrs, DoneSetStat 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. + */ + IToken fsetstat(IFileHandle handle, FileAttrs attrs, DoneSetStat done); + + interface DoneSetStat { + void doneSetStat(IToken token, FileSystemException error); + } + + /** + * 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. + */ + IToken opendir(String path, DoneOpen 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. + */ + IToken readdir(IFileHandle handle, DoneReadDir done); + + interface DoneReadDir { + void doneReadDir(IToken token, FileSystemException error, DirEntry[] entries, boolean eof); + } + + /** + * 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. + */ + IToken mkdir(String path, FileAttrs attrs, DoneMkDir done); + + interface DoneMkDir { + void doneMkDir(IToken token, FileSystemException error); + } + + /** + * 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. + */ + IToken rmdir(String path, DoneRemove done); + + interface DoneRemove { + void doneRemove(IToken token, FileSystemException error); + } + + /** + * 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. + */ + IToken roots(DoneRoots done); + + interface DoneRoots { + void doneRoots(IToken token, FileSystemException error, DirEntry[] entries); + } + + /** + * 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. + */ + IToken remove(String file_name, DoneRemove 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. + */ + IToken realpath(String path, DoneRealPath done); + + interface DoneRealPath { + void doneRealPath(IToken token, FileSystemException error, String path); + } + + /** + * 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. + */ + IToken rename(String old_path, String new_path, DoneRename done); + + interface DoneRename { + void doneRename(IToken token, FileSystemException error); + } + + /** + * 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. + */ + IToken readlink(String path, DoneReadLink done); + + interface DoneReadLink { + void doneReadLink(IToken token, FileSystemException error, String path); + } + + /** + * 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. + */ + IToken symlink(String link_path, String target_path, DoneSymLink done); + + interface DoneSymLink { + void doneSymLink(IToken token, FileSystemException error); + } + + /** + * 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. + */ + IToken copy(String src_path, String dst_path, + boolean copy_permissions, boolean copy_ownership, DoneCopy done); + + interface DoneCopy { + void doneCopy(IToken token, FileSystemException error); + } + + /** + * 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. + */ + IToken user(DoneUser done); + + interface DoneUser { + void doneUser(IToken token, FileSystemException error, + int real_uid, int effective_uid, int real_gid, int effective_gid, + String home); + } +} |