File indexing completed on 2024-12-22 04:41:40
0001 /* 0002 * SPDX-FileCopyrightText: 2018 Erik Duisters <e.duisters1@gmail.com> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 package org.kde.kdeconnect.Plugins.SftpPlugin; 0008 0009 import android.content.Context; 0010 import android.net.Uri; 0011 import android.util.Log; 0012 0013 import org.apache.commons.io.FileUtils; 0014 import org.apache.sshd.common.file.nativefs.NativeSshFile; 0015 import org.kde.kdeconnect.Helpers.MediaStoreHelper; 0016 0017 import java.io.File; 0018 import java.io.FileOutputStream; 0019 import java.io.IOException; 0020 import java.io.OutputStream; 0021 import java.io.RandomAccessFile; 0022 0023 class AndroidSshFile extends NativeSshFile { 0024 private static final String TAG = AndroidSshFile.class.getSimpleName(); 0025 final private Context context; 0026 final private File file; 0027 0028 AndroidSshFile(final AndroidFileSystemView view, String name, final File file, final String userName, Context context) { 0029 super(view, name, file, userName); 0030 this.context = context; 0031 this.file = file; 0032 } 0033 0034 @Override 0035 public OutputStream createOutputStream(long offset) throws IOException { 0036 if (!isWritable()) { 0037 throw new IOException("No write permission : " + file.getName()); 0038 } 0039 0040 final RandomAccessFile raf = new RandomAccessFile(file, "rw"); 0041 try { 0042 if (offset < raf.length()) { 0043 throw new IOException("Your SSHFS is bugged"); //SSHFS 3.0 and 3.2 cause data corruption, abort the transfer if this happens 0044 } 0045 raf.setLength(offset); 0046 raf.seek(offset); 0047 0048 return new FileOutputStream(raf.getFD()) { 0049 public void close() throws IOException { 0050 super.close(); 0051 raf.close(); 0052 } 0053 }; 0054 } catch (IOException e) { 0055 raf.close(); 0056 throw e; 0057 } 0058 } 0059 0060 @Override 0061 public boolean delete() { 0062 boolean ret = super.delete(); 0063 if (ret) { 0064 MediaStoreHelper.indexFile(context, Uri.fromFile(file)); 0065 } 0066 return ret; 0067 0068 } 0069 0070 @Override 0071 public boolean create() throws IOException { 0072 boolean ret = super.create(); 0073 if (ret) { 0074 MediaStoreHelper.indexFile(context, Uri.fromFile(file)); 0075 } 0076 return ret; 0077 0078 } 0079 0080 // Based on https://github.com/wolpi/prim-ftpd/blob/master/primitiveFTPd/src/org/primftpd/filesystem/FsFile.java 0081 @Override 0082 public boolean doesExist() { 0083 boolean exists = file.exists(); 0084 0085 if (!exists) { 0086 // file.exists() returns false when we don't have read permission 0087 // try to figure out if it really does not exist 0088 try { 0089 exists = FileUtils.directoryContains(file.getParentFile(), file); 0090 } catch (IOException | IllegalArgumentException e) { 0091 // An IllegalArgumentException is thrown if the parent is null or not a directory. 0092 Log.d(TAG, "Exception: ", e); 0093 } 0094 } 0095 0096 return exists; 0097 } 0098 }