All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.schmizz.sshj.sftp.SFTPEngine Maven / Gradle / Ivy
/*
* Copyright 2010 Shikhar Bhushan
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.schmizz.sshj.sftp;
import net.schmizz.sshj.common.SSHException;
import net.schmizz.sshj.connection.channel.direct.Session.Subsystem;
import net.schmizz.sshj.connection.channel.direct.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.io.IOException;
import java.io.OutputStream;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class SFTPEngine
implements Requester, Closeable {
public static final int MAX_SUPPORTED_VERSION = 3;
public static final int DEFAULT_TIMEOUT = 30;
/** Logger */
protected final Logger log = LoggerFactory.getLogger(getClass());
protected volatile int timeout = DEFAULT_TIMEOUT;
protected final Subsystem sub;
protected final PacketReader reader;
protected final OutputStream out;
protected long reqID;
protected int operativeVersion;
protected final Map serverExtensions = new HashMap();
public SFTPEngine(SessionFactory ssh)
throws SSHException {
sub = ssh.startSession().startSubsystem("sftp");
out = sub.getOutputStream();
reader = new PacketReader(this);
}
public SFTPEngine init()
throws IOException {
transmit(new SFTPPacket(PacketType.INIT).putInt(MAX_SUPPORTED_VERSION));
final SFTPPacket response = reader.readPacket();
final PacketType type = response.readType();
if (type != PacketType.VERSION)
throw new SFTPException("Expected INIT packet, received: " + type);
operativeVersion = response.readInt();
log.info("Server version {}", operativeVersion);
if (MAX_SUPPORTED_VERSION < operativeVersion)
throw new SFTPException("Server reported incompatible protocol version: " + operativeVersion);
while (response.available() > 0)
serverExtensions.put(response.readString(), response.readString());
// Start reader thread
reader.start();
return this;
}
public Subsystem getSubsystem() {
return sub;
}
public int getOperativeProtocolVersion() {
return operativeVersion;
}
public Request newExtendedRequest(String reqName) {
return newRequest(PacketType.EXTENDED).putString(reqName);
}
@Override
public synchronized Request newRequest(PacketType type) {
return new Request(type, reqID = reqID + 1 & 0xffffffffL);
}
@Override
public Response doRequest(Request req)
throws IOException {
reader.expectResponseTo(req);
log.debug("Sending {}", req);
transmit(req);
return req.getResponseFuture().get(timeout, TimeUnit.SECONDS);
}
public RemoteFile open(String path, Set modes, FileAttributes fa)
throws IOException {
final String handle = doRequest(
newRequest(PacketType.OPEN).putString(path).putInt(OpenMode.toMask(modes)).putFileAttributes(fa)
).ensurePacketTypeIs(PacketType.HANDLE).readString();
return new RemoteFile(this, path, handle);
}
public RemoteFile open(String filename, Set modes)
throws IOException {
return open(filename, modes, FileAttributes.EMPTY);
}
public RemoteFile open(String filename)
throws IOException {
return open(filename, EnumSet.of(OpenMode.READ));
}
public RemoteDirectory openDir(String path)
throws IOException {
final String handle = doRequest(
newRequest(PacketType.OPENDIR).putString(path)
).ensurePacketTypeIs(PacketType.HANDLE).readString();
return new RemoteDirectory(this, path, handle);
}
public void setAttributes(String path, FileAttributes attrs)
throws IOException {
doRequest(
newRequest(PacketType.SETSTAT).putString(path).putFileAttributes(attrs)
).ensureStatusPacketIsOK();
}
public String readLink(String path)
throws IOException {
if (operativeVersion < 3)
throw new SFTPException("READLINK is not supported in SFTPv" + operativeVersion);
return readSingleName(
doRequest(
newRequest(PacketType.READLINK).putString(path)
));
}
public void makeDir(String path, FileAttributes attrs)
throws IOException {
doRequest(newRequest(PacketType.MKDIR).putString(path).putFileAttributes(attrs)).ensureStatusPacketIsOK();
}
public void makeDir(String path)
throws IOException {
makeDir(path, FileAttributes.EMPTY);
}
public void symlink(String linkpath, String targetpath)
throws IOException {
if (operativeVersion < 3)
throw new SFTPException("SYMLINK is not supported in SFTPv" + operativeVersion);
doRequest(
newRequest(PacketType.SYMLINK).putString(linkpath).putString(targetpath)
).ensureStatusPacketIsOK();
}
public void remove(String filename)
throws IOException {
doRequest(
newRequest(PacketType.REMOVE).putString(filename)
).ensureStatusPacketIsOK();
}
public void removeDir(String path)
throws IOException {
doRequest(
newRequest(PacketType.RMDIR).putString(path)
).ensureStatusIs(Response.StatusCode.OK);
}
public FileAttributes stat(String path)
throws IOException {
return stat(PacketType.STAT, path);
}
public FileAttributes lstat(String path)
throws IOException {
return stat(PacketType.LSTAT, path);
}
public void rename(String oldPath, String newPath)
throws IOException {
if (operativeVersion < 1)
throw new SFTPException("RENAME is not supported in SFTPv" + operativeVersion);
doRequest(
newRequest(PacketType.RENAME).putString(oldPath).putString(newPath)
).ensureStatusPacketIsOK();
}
public String canonicalize(String path)
throws IOException {
return readSingleName(
doRequest(
newRequest(PacketType.REALPATH).putString(path)
));
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public int getTimeout() {
return timeout;
}
@Override
public void close()
throws IOException {
sub.close();
}
protected FileAttributes stat(PacketType pt, String path)
throws IOException {
return doRequest(newRequest(pt).putString(path))
.ensurePacketTypeIs(PacketType.ATTRS)
.readFileAttributes();
}
protected static String readSingleName(Response res)
throws IOException {
res.ensurePacketTypeIs(PacketType.NAME);
if (res.readInt() == 1)
return res.readString();
else
throw new SFTPException("Unexpected data in " + res.getType() + " packet");
}
protected synchronized void transmit(SFTPPacket payload)
throws IOException {
final int len = payload.available();
out.write((len >>> 24) & 0xff);
out.write((len >>> 16) & 0xff);
out.write((len >>> 8) & 0xff);
out.write(len & 0xff);
out.write(payload.array(), payload.rpos(), len);
out.flush();
}
}