Skip to content

Commit

Permalink
Merge pull request #346 from lmagyar/pr-fix-new-file-upload-with-sshfs
Browse files Browse the repository at this point in the history
Fix new file upload on SAF and VirtualFS with SSHFS
  • Loading branch information
wolpi authored Jun 26, 2024
2 parents 14cf6f0 + 7145dc1 commit c282b4f
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 1 deletion.
26 changes: 25 additions & 1 deletion primitiveFTPd/src/org/primftpd/filesystem/SafFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public abstract class SafFile<T> extends AbstractFile {
private DocumentFile documentFile;
private final DocumentFile parentDocumentFile;

private final boolean writable;
private boolean writable;

public SafFile(
ContentResolver contentResolver,
Expand Down Expand Up @@ -225,4 +225,28 @@ public InputStream createInputStream(long offset) throws IOException {

return null;
}

// This method is the equivalent of java.io.File.createNewFile(), it creates the file and updates the cached properties of it.
// This method is required by SSHFS, because it calls STAT and later FSTAT on created new files,
// STAT requires a created new file, FSTAT requires updated properties.
// This method is not required by normal clients who simply open, write and close the file.
boolean createNewFile() throws IOException {
logger.trace("[{}] createNewFile()", name);
try {
documentFile = parentDocumentFile.createFile(null, name);
} catch (Exception e) {
throw new IOException("Failed to create file", e);
}

if (documentFile != null) {
lastModified = documentFile.lastModified();
size = 0;
readable = documentFile.canRead();
exists = true;
writable = documentFile.canWrite();
return true;
}

return false;
}
}
10 changes: 10 additions & 0 deletions primitiveFTPd/src/org/primftpd/filesystem/SafSshFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.apache.sshd.common.file.SshFile;
import org.primftpd.services.PftpdService;

import java.io.IOException;
import java.util.List;

public class SafSshFile extends SafFile<SshFile> implements SshFile {
Expand Down Expand Up @@ -67,6 +68,15 @@ public String getOwner() {
return session.getUsername();
}

@Override
public boolean create() throws IOException {
logger.trace("[{}] create()", name);
// This call is required by SSHFS, because it calls STAT and later FSTAT on created new files,
// STAT requires a created new file, FSTAT requires updated properties.
// This call is not required by normal clients who simply open, write and close the file.
return createNewFile();
}

@Override
public SshFile getParentFile() {
logger.trace("[{}] getParentFile()", name);
Expand Down
17 changes: 17 additions & 0 deletions primitiveFTPd/src/org/primftpd/filesystem/VirtualSshFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.apache.sshd.common.file.SshFile;
import org.primftpd.services.PftpdService;

import java.io.IOException;
import java.util.List;

public class VirtualSshFile extends VirtualFile<SshFile> implements SshFile {
Expand Down Expand Up @@ -53,6 +54,22 @@ public String getOwner() {
return session.getUsername();
}

@Override
public boolean create() throws IOException {
logger.trace("[{}] create()", name);
// This call and the update of the cached properties is required by SSHFS, because it calls STAT and later FSTAT on created new files,
// STAT requires a created new file, FSTAT requires updated properties.
// This call is not required by normal clients who simply open, write and close the file.
if (delegate != null && ((SshFile) delegate).create()) {
lastModified = delegate.getLastModified();
size = 0;
readable = delegate.isReadable();
exists = true;
return true;
}
return false;
}

@Override
public boolean isExecutable() {
logger.trace("[{}] isExecutable()", name);
Expand Down

0 comments on commit c282b4f

Please sign in to comment.