summaryrefslogtreecommitdiff
path: root/libs/samba/src/main/java/org/the_jk/cleversync
diff options
context:
space:
mode:
authorJoel Klinghed <the_jk@spawned.biz>2024-07-22 23:06:16 +0200
committerJoel Klinghed <the_jk@spawned.biz>2024-07-23 00:04:58 +0200
commit09bc93ed756361d396890c389b01315cdb5e32fd (patch)
tree3a2718a2b5a3584a489d009a532526239f6b45a5 /libs/samba/src/main/java/org/the_jk/cleversync
parent42564c71cfb70c28831c662a3b6bf4084e079353 (diff)
Add initial code for samba implementation based on libsmb2
Diffstat (limited to 'libs/samba/src/main/java/org/the_jk/cleversync')
-rw-r--r--libs/samba/src/main/java/org/the_jk/cleversync/io/samba/NativeSamba.kt92
-rw-r--r--libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaConnection.kt32
-rw-r--r--libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaDirectory.kt88
-rw-r--r--libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaTree.kt10
-rw-r--r--libs/samba/src/main/java/org/the_jk/cleversync/samba/SambaTreeFactory.kt17
5 files changed, 239 insertions, 0 deletions
diff --git a/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/NativeSamba.kt b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/NativeSamba.kt
new file mode 100644
index 0000000..360aaa9
--- /dev/null
+++ b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/NativeSamba.kt
@@ -0,0 +1,92 @@
+// Using RegisterNatives
+@file:Suppress("KotlinJniMissingFunction")
+
+package org.the_jk.cleversync.io.samba
+
+import androidx.annotation.Keep
+
+@Keep
+internal object NativeSamba {
+ fun newContext(): Context = NativeContext(nativeContextNew())
+
+ interface Object {
+ fun destroy()
+ }
+
+ interface Context : Object {
+ fun parseUrl(url: String): Url?
+ fun connect(url: Url): Boolean
+ fun lastError(): String
+ fun openDir(path: String): Dir?
+ }
+
+ interface Url : Object {
+ fun path(): String
+ }
+
+ interface Dir : Object {
+ val path: String
+ }
+
+ private class NativeContext(private var ptr: Long): Context {
+ override fun destroy() {
+ if (ptr == 0L) return
+ nativeContextDestroy(ptr)
+ ptr = 0L
+ }
+
+ override fun parseUrl(url: String): Url? {
+ val ptr = nativeContextParseUrl(ptr, url)
+ return if (ptr != 0L) NativeUrl(ptr) else null
+ }
+
+ override fun connect(url: Url): Boolean {
+ return nativeContextConnect(ptr, (url as NativeUrl).get())
+ }
+
+ override fun lastError(): String {
+ return nativeContextGetError(ptr)
+ }
+
+ override fun openDir(path: String): Dir? {
+ val dir = nativeContextOpenDir(ptr, path)
+ return if (dir != 0L) NativeDir(path, dir) else null
+ }
+ }
+
+ private class NativeUrl(private var ptr: Long): Url {
+ override fun destroy() {
+ if (ptr == 0L) return
+ nativeUrlDestroy(ptr)
+ ptr = 0L
+ }
+
+ override fun path(): String = nativeUrlPath(ptr)
+
+ fun get(): Long = ptr
+ }
+
+ private class NativeDir(override val path: String, private var ptr: Long): Dir {
+ override fun destroy() {
+ if (ptr == 0L) return
+ nativeDirDestroy(ptr)
+ ptr = 0L
+ }
+ }
+
+ init {
+ System.loadLibrary("samba")
+ }
+
+ private external fun nativeContextNew(): Long
+ private external fun nativeContextDestroy(ptr: Long)
+ private external fun nativeContextParseUrl(ptr: Long, url: String): Long
+ private external fun nativeContextConnect(ptr: Long, url: Long): Boolean
+ private external fun nativeContextGetError(ptr: Long): String
+ private external fun nativeContextOpenDir(ptr: Long, path: String): Long
+
+ private external fun nativeUrlDestroy(ptr: Long)
+ private external fun nativeUrlPath(ptr: Long): String
+
+ private external fun nativeDirDestroy(ptr: Long)
+}
diff --git a/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaConnection.kt b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaConnection.kt
new file mode 100644
index 0000000..03d3a9e
--- /dev/null
+++ b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaConnection.kt
@@ -0,0 +1,32 @@
+package org.the_jk.cleversync.io.samba
+
+internal class SambaConnection(uri: String) {
+ private val context = NativeSamba.newContext()
+ private val url = context.parseUrl(uri)
+
+ val connected = if (url != null) { context.connect(url) } else false
+
+ val error: String
+ get() = context.lastError()
+
+ fun openDir(path: String): NativeSamba.Dir? =
+ if (connected) context.openDir(join(url!!.path(), path)) else null
+
+ companion object {
+ fun join(a: String, b: String): String {
+ if (a.isEmpty() || b.startsWith("/")) return b
+ if (b.isEmpty()) return a
+ return if (a.endsWith("/")) a + b else "${a}/${b}"
+ }
+
+ fun dirname(path: String): String {
+ val last = path.lastIndexOf('/')
+ return if (last == -1) path else path.substring(last + 1)
+ }
+
+ fun basename(path: String): String {
+ val last = path.lastIndexOf('/')
+ return if (last < 1) "" else path.substring(0, last - 1)
+ }
+ }
+}
diff --git a/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaDirectory.kt b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaDirectory.kt
new file mode 100644
index 0000000..b82e745
--- /dev/null
+++ b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaDirectory.kt
@@ -0,0 +1,88 @@
+package org.the_jk.cleversync.io.samba
+
+import androidx.lifecycle.LiveData
+import org.the_jk.cleversync.io.Directory
+import org.the_jk.cleversync.io.File
+import org.the_jk.cleversync.io.Link
+import org.the_jk.cleversync.io.ModifiableDirectory
+import org.the_jk.cleversync.io.ModifiableFile
+import org.the_jk.cleversync.io.ModifiableLink
+
+internal open class SambaDirectory(
+ private val conn: SambaConnection,
+ private val dir: NativeSamba.Dir,
+) : ModifiableDirectory {
+ override fun modifiableOpenDir(name: String): ModifiableDirectory? {
+ val dir = conn.openDir(SambaConnection.join(dir.path, name)) ?: return null
+ return SambaDirectory(conn, dir)
+ }
+
+ override fun modifiableOpenFile(name: String): ModifiableFile? {
+ TODO("Not yet implemented")
+ }
+
+ override fun modifiableOpenLink(name: String): ModifiableLink? {
+ TODO("Not yet implemented")
+ }
+
+ override fun modifiableList(): ModifiableDirectory.Content {
+ TODO("Not yet implemented")
+ }
+
+ override fun modifiableLiveList(): LiveData<ModifiableDirectory.Content> {
+ TODO("Not yet implemented")
+ }
+
+ override fun createDirectory(name: String): ModifiableDirectory {
+ TODO("Not yet implemented")
+ }
+
+ override fun createFile(name: String): ModifiableFile {
+ TODO("Not yet implemented")
+ }
+
+ override fun createLink(name: String, target: Directory): ModifiableLink {
+ TODO("Not yet implemented")
+ }
+
+ override fun createLink(name: String, target: File): ModifiableLink {
+ TODO("Not yet implemented")
+ }
+
+ override fun createLink(name: String, target: String): ModifiableLink {
+ TODO("Not yet implemented")
+ }
+
+ override fun removeDirectory(name: String): Boolean {
+ TODO("Not yet implemented")
+ }
+
+ override fun removeFile(name: String): Boolean {
+ TODO("Not yet implemented")
+ }
+
+ override fun removeLink(name: String): Boolean {
+ TODO("Not yet implemented")
+ }
+
+ override val name: String
+ get() = SambaConnection.dirname(dir.path)
+
+ override fun openDir(name: String) = modifiableOpenDir(name)
+
+ override fun openFile(name: String): File? {
+ TODO("Not yet implemented")
+ }
+
+ override fun openLink(name: String): Link? {
+ TODO("Not yet implemented")
+ }
+
+ override fun list(): Directory.Content {
+ TODO("Not yet implemented")
+ }
+
+ override fun liveList(): LiveData<Directory.Content> {
+ TODO("Not yet implemented")
+ }
+}
diff --git a/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaTree.kt b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaTree.kt
new file mode 100644
index 0000000..8b4a86d
--- /dev/null
+++ b/libs/samba/src/main/java/org/the_jk/cleversync/io/samba/SambaTree.kt
@@ -0,0 +1,10 @@
+package org.the_jk.cleversync.io.samba
+
+import android.content.res.Resources
+import org.the_jk.cleversync.io.ModifiableTree
+
+internal class SambaTree(conn: SambaConnection, root: NativeSamba.Dir) : SambaDirectory(conn, root), ModifiableTree {
+ override fun description(resources: Resources): CharSequence {
+ TODO("Not yet implemented")
+ }
+}
diff --git a/libs/samba/src/main/java/org/the_jk/cleversync/samba/SambaTreeFactory.kt b/libs/samba/src/main/java/org/the_jk/cleversync/samba/SambaTreeFactory.kt
new file mode 100644
index 0000000..3455de8
--- /dev/null
+++ b/libs/samba/src/main/java/org/the_jk/cleversync/samba/SambaTreeFactory.kt
@@ -0,0 +1,17 @@
+package org.the_jk.cleversync.samba
+
+import org.the_jk.cleversync.io.ModifiableTree
+import org.the_jk.cleversync.io.Tree
+import org.the_jk.cleversync.io.samba.SambaConnection
+import org.the_jk.cleversync.io.samba.SambaTree
+
+object SambaTreeFactory {
+ fun tree(uri: String): Result<Tree> = modifiableTree(uri)
+
+ fun modifiableTree(uri: String): Result<ModifiableTree> {
+ val connection = SambaConnection(uri)
+ if (!connection.connected) return Result.failure(Exception(connection.error))
+ val root = connection.openDir("") ?: return Result.failure(Exception(connection.error))
+ return Result.success(SambaTree(connection, root))
+ }
+}