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 }