Skip to content

Commit

Permalink
Merge pull request #3888 from TranceLove/bugfix/ssh-copy-fixes-2
Browse files Browse the repository at this point in the history
Bugfix/ssh copy fixes 2
  • Loading branch information
VishalNehra authored Sep 18, 2023
2 parents 9f5ba39 + 6dd0bb2 commit 247d880
Show file tree
Hide file tree
Showing 13 changed files with 420 additions and 339 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ class CalculateHashTask(

private val log: Logger = LoggerFactory.getLogger(CalculateHashTask::class.java)

private val task: Callable<Hash> = if (file.isSftp) {
private val task: Callable<Hash> = if (file.isSftp && !file.isDirectory(context)) {
CalculateHashSftpCallback(file)
} else if (file.isFtp) {
} else if (file.isFtp || file.isDirectory(context)) {
// Don't do this. Especially when FTPClient requires thread safety.
DoNothingCalculateHashCallback()
} else {
Expand Down
190 changes: 97 additions & 93 deletions app/src/main/java/com/amaze/filemanager/filesystem/HybridFile.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ public HybridFileParcelable(String path, boolean isDirectory, RemoteResourceInfo
Integer.toString(FilePermission.toMask(sshFile.getAttributes().getPermissions()), 8));
}

@Override
public long lastModified() {
return date;
}

public String getName() {
if (!Utils.isNullOrEmpty(name)) return name;
else return super.getSimpleName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import com.amaze.filemanager.filesystem.root.MakeFileCommand;
import com.amaze.filemanager.filesystem.root.RenameFileCommand;
import com.amaze.filemanager.filesystem.ssh.SFtpClientTemplate;
import com.amaze.filemanager.filesystem.ssh.SshClientUtils;
import com.amaze.filemanager.utils.DataUtils;
import com.amaze.filemanager.utils.OTGUtil;
import com.cloudrail.si.interfaces.CloudStorage;
Expand All @@ -67,7 +68,7 @@

public class Operations {

private static Executor executor = AsyncTask.THREAD_POOL_EXECUTOR;
private static final Executor executor = AsyncTask.THREAD_POOL_EXECUTOR;

private static final Logger LOG = LoggerFactory.getLogger(Operations.class);

Expand Down Expand Up @@ -579,14 +580,14 @@ protected Void doInBackground(Void... params) {
}
return null;
} else if (oldFile.isSftp()) {
NetCopyClientUtils.INSTANCE.execute(
new SFtpClientTemplate<Void>(oldFile.getPath(), false) {
SshClientUtils.execute(
new SFtpClientTemplate<Void>(oldFile.getPath(), true) {
@Override
public Void execute(@NonNull SFTPClient client) {
try {
client.rename(
NetCopyClientUtils.INSTANCE.extractRemotePathFrom(oldFile.getPath()),
NetCopyClientUtils.INSTANCE.extractRemotePathFrom(newFile.getPath()));
NetCopyClientUtils.extractRemotePathFrom(oldFile.getPath()),
NetCopyClientUtils.extractRemotePathFrom(newFile.getPath()));
errorCallBack.done(newFile, true);
} catch (IOException e) {
String errmsg =
Expand Down Expand Up @@ -620,8 +621,8 @@ public Boolean executeWithFtpClient(@NonNull FTPClient ftpClient)
throws IOException {
boolean result =
ftpClient.rename(
NetCopyClientUtils.INSTANCE.extractRemotePathFrom(oldFile.getPath()),
NetCopyClientUtils.INSTANCE.extractRemotePathFrom(newFile.getPath()));
NetCopyClientUtils.extractRemotePathFrom(oldFile.getPath()),
NetCopyClientUtils.extractRemotePathFrom(newFile.getPath()));
errorCallBack.done(newFile, result);
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,10 @@ private void startCopy(

doCopy(inChannel, outChannel, updatePosition);
} catch (IOException e) {
LOG.debug("I/O Error!", e);
throw new IOException();
LOG.error("I/O Error copy {} to {}: {}", mSourceFile, mTargetFile, e);
throw new IOException(e);
} catch (OutOfMemoryError e) {
LOG.warn("low memory while copying file", e);
LOG.warn("low memory while copying {} to {}: {}", mSourceFile, mTargetFile, e);

onLowMemory.onLowMemory();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,6 @@ object NetCopyClientConnectionPool {
/**
* Obtain a [NetCopyClient] connection from the underlying connection pool.
*
*
* Beneath it will return the connection if it exists; otherwise it will create a new one and
* put it into the connection pool.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ import org.apache.commons.net.ftp.FTPClient
import org.apache.commons.net.ftp.FTPReply
import org.slf4j.LoggerFactory
import java.io.IOException
import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale

object NetCopyClientUtils {

Expand All @@ -74,7 +78,9 @@ object NetCopyClientUtils {
* Execute the given NetCopyClientTemplate.
*
* This template pattern is borrowed from Spring Framework, to simplify code on operations
* using SftpClientTemplate.
* using NetCopyClientTemplate.
*
* FIXME: Over-simplification implementation causing unnecessarily closing SSHClient.
*
* @param template [NetCopyClientTemplate] to execute
* @param <T> Type of return value
Expand Down Expand Up @@ -187,6 +193,7 @@ object NetCopyClientUtils {
* @param fullUri Full SSH URL
* @return The remote path part of the full SSH URL
*/
@JvmStatic
fun extractRemotePathFrom(fullUri: String): String {
return NetCopyConnectionInfo(fullUri).let { connInfo ->
if (true == connInfo.defaultPath?.isNotEmpty()) {
Expand Down Expand Up @@ -291,4 +298,16 @@ object NetCopyClientUtils {
SMB_URI_PREFIX -> 0 // SMB never requires explicit port number at URL
else -> throw IllegalArgumentException("Cannot derive default port")
}

/**
* Convenience method to format given UNIX timestamp to yyyyMMddHHmmss format.
*/
@JvmStatic
fun getTimestampForTouch(date: Long): String {
val calendar = Calendar.getInstance()
calendar.timeInMillis = date
val df: DateFormat = SimpleDateFormat("yyyyMMddHHmmss", Locale.US)
df.calendar = calendar
return df.format(calendar.time)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright (C) 2014-2023 Arpit Khurana <[email protected]>, Vishal Nehra <[email protected]>,
* Emmanuel Messulam<[email protected]>, Raymond Lai <airwave209gt at gmail.com> and Contributors.
*
* This file is part of Amaze File Manager.
*
* Amaze File Manager is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.amaze.filemanager.filesystem.ssh

import net.schmizz.sshj.sftp.FileAttributes
import net.schmizz.sshj.sftp.OpenMode
import net.schmizz.sshj.sftp.PacketType
import net.schmizz.sshj.sftp.RemoteFile
import net.schmizz.sshj.sftp.SFTPClient
import net.schmizz.sshj.sftp.SFTPEngine
import java.io.IOException
import java.util.EnumSet
import java.util.concurrent.TimeUnit

const val READ_AHEAD_MAX_UNCONFIRMED_READS: Int = 16

/**
* Monkey-patch [SFTPEngine.open] until sshj adds back read ahead support in [RemoteFile].
*/
@Throws(IOException::class)
fun SFTPEngine.openWithReadAheadSupport(
path: String,
modes: Set<OpenMode>,
fa: FileAttributes
): RemoteFile {
val handle: ByteArray = request(
newRequest(PacketType.OPEN).putString(path, subsystem.remoteCharset)
.putUInt32(OpenMode.toMask(modes).toLong()).putFileAttributes(fa)
).retrieve(timeoutMs.toLong(), TimeUnit.MILLISECONDS)
.ensurePacketTypeIs(PacketType.HANDLE).readBytes()
return RemoteFile(this, path, handle)
}

/**
* Monkey-patch [SFTPClient.open] until sshj adds back read ahead support in [RemoteFile].
*/
fun SFTPClient.openWithReadAheadSupport(path: String): RemoteFile {
return sftpEngine.openWithReadAheadSupport(
path,
EnumSet.of(OpenMode.READ),
FileAttributes.EMPTY
)
}
Loading

0 comments on commit 247d880

Please sign in to comment.