X-Git-Url: https://git.distorted.org.uk/~mdw/tripe-android/blobdiff_plain/8eabb4ff13562f3550499ee599297f7e97fa8754..25c3546915ef2105c0d53983939da840ddbde795:/jni.scala diff --git a/jni.scala b/jni.scala deleted file mode 100644 index ea6ae76..0000000 --- a/jni.scala +++ /dev/null @@ -1,246 +0,0 @@ -/* -*-java-*- - * - * Declarations of C functions - * - * (c) 2018 Straylight/Edgeware - */ - -/*----- Licensing notice --------------------------------------------------* - * - * This file is part of the Trivial IP Encryption (TrIPE) Android app. - * - * TrIPE 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. - * - * TrIPE 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 TrIPE. If not, see . - */ - -package uk.org.distorted.tripe; package object jni { - -/*----- Imports -----------------------------------------------------------*/ - -import java.io.{Closeable, File}; -import java.util.Date; -import Magic._; - -/*----- Main code ---------------------------------------------------------*/ - -/* Import the native code library. */ -System.loadLibrary("toy"); - -/* Exception indicating that a wrapped native object has been clobbered. */ -class NativeObjectTypeException(msg: String) extends RuntimeException(msg); -type Wrapper = Array[Byte]; - -case class ErrorEntry(val tag: String, val err: Int); -@native def errtab: Array[ErrorEntry]; -@native def strerror(err: Int): CString; - -@native def hashsz(hash: String): Int; - /* Return the output hash size for the named HASH function, or -1. */ - -/* Flags for `close'. */ -val CF_CLOSERD = 1; -val CF_CLOSEWR = 2; -val CF_CLOSEMASK = CF_CLOSERD | CF_CLOSEWR; - -/* Flags for `lock'. */ -val LKF_EXCL = 1; -val LKF_WAIT = 2; - -/* Flags for `stat'. */ -val S_IFMT = 0xf000; -val S_IFIFO = 0x1000; -val S_IFCHR = 0x2000; -val S_IFDIR = 0x4000; -val S_IFBLK = 0x6000; -val S_IFREG = 0x8000; -val S_IFLNK = 0xa000; -val S_IFSOCK = 0xc000; - -object FileType extends Enumeration { - val FIFO, CHR, DIR, BLK, REG, LNK, SOCK, UNK = Value; -} -import FileType.{Value => _, _}; - -class FileInfo private[this](val devMajor: Int, val devMinor: Int, - val ino: Long, val mode: Int, val nlink: Int, - val uid: Int, val gid: Int, - _rdevMinor: Int, _rdevMajor: Int, - val size: Long, - val blksize: Int, val blocks: Long, - val atime: Date, val mtime: Date, - val ctime: Date) { - def this(devMajor: Int, devMinor: Int, ino: Long, - mode: Int, nlink: Int, uid: Int, gid: Int, - rdevMinor: Int, rdevMajor: Int, - size: Long, blksize: Int, blocks: Long, - atime: Long, mtime: Long, ctime: Long) { - this(devMajor, devMinor, ino, mode, nlink, uid, gid, - rdevMajor, rdevMinor, size, blksize, blocks, - new Date(atime), new Date(mtime), new Date(ctime)); - } - def perms: Int = mode&0xfff; - def ftype: FileType.Value = (mode&S_IFMT) match { - case S_IFIFO => FIFO - case S_IFCHR => CHR - case S_IFDIR => DIR - case S_IFBLK => BLK - case S_IFREG => REG - case S_IFLNK => LNK - case S_IFSOCK => SOCK - case _ => UNK - } - def isfifo: Boolean = ftype == FIFO - def ischr: Boolean = ftype == CHR - def isdir: Boolean = ftype == DIR - def isblk: Boolean = ftype == BLK - def isreg: Boolean = ftype == REG - def islnk: Boolean = ftype == LNK - def issock: Boolean = ftype == SOCK - def isdev: Boolean = ischr || isblk; - private[this] def mustBeDevice() { - if (!isdev) throw new IllegalArgumentException("Object is not a device"); - } - def rdevMajor: Int = { mustBeDevice(); _rdevMajor } - def rdevMinor: Int = { mustBeDevice(); _rdevMinor } -} -@native protected def unlink(path: CString); -def unlink(path: String) { unlink(path.toCString); } -def unlink(file: File) { unlink(file.getPath); } -@native protected def rmdir(path: CString); -def rmdir(path: String) { rmdir(path.toCString); } -def rmdir(file: File) { rmdir(file.getPath); } -@native protected def mkdir(path: CString, mode: Int); -def mkdir(path: String, mode: Int) { mkdir(path.toCString, mode); } -def mkdir(path: String) { mkdir(path, 0x1ff); } -def mkdir(file: File, mode: Int) { mkdir(file.getPath, mode); } -def mkdir(file: File) { mkdir(file.getPath); } -@native protected def mkfile(path: CString, mode: Int); -def mkfile(path: String, mode: Int) { mkfile(path.toCString, mode); } -def mkfile(path: String) { mkfile(path, 0x1b6); } -def mkfile(file: File, mode: Int) { mkfile(file.getPath, mode); } -def mkfile(file: File) { mkfile(file.getPath); } -@native protected def rename(from: CString, to: CString); -def rename(from: String, to: String) - { rename(from.toCString, to.toCString); } -def rename(from: File, to: File) - { rename(from.getPath, to.getPath); } -@native protected def stat(path: CString): FileInfo; -def stat(path: String): FileInfo = stat(path.toCString); -def stat(file: File): FileInfo = stat(file.getPath); -@native protected def lstat(path: CString): FileInfo; -def lstat(path: String): FileInfo = lstat(path.toCString); -def lstat(file: File): FileInfo = lstat(file.getPath); - -@native protected def opendir(path: CString): Wrapper; -@native protected def readdir(path: CString, dir: Wrapper): CString; -@native protected def closedir(path: CString, dir: Wrapper); - -abstract class BaseDirIterator[T](cpath: CString) - extends LookaheadIterator[T] with Closeable { - def this(path: String) { this(path.toCString); } - def this(dir: File) { this(dir.getPath); } - override def close() { closedir(cpath, dir); } - override protected def finalize() { super.finalize(); close(); } - private[this] val dir = opendir(cpath); - protected def mangle(file: String): T; - override protected def fetch(): Option[T] = readdir(cpath, dir) match { - case null => None - case f => f.toJString match { - case "." | ".." => fetch() - case jf => Some(mangle(jf)) - } - } -} - -class DirIterator(val path: String) extends BaseDirIterator[String](path) { - def this(dir: File) { this(dir.getPath); } - override protected def mangle(file: String): String = file; -} -def listDir(path: String): List[String] = { - val iter = new DirIterator(path); - try { iter.toList } - finally { iter.close(); } -} -def listDir(dir: File): List[String] = listDir(dir.getPath); - -class DirFilesIterator private[this](val dir: File, cpath: CString) - extends BaseDirIterator[File](cpath) { - def this(dir: File) { this(dir, dir.getPath.toCString); } - def this(path: String) { this(new File(path), path.toCString); } - override protected def mangle(file: String): File = new File(dir, file); -} -def listDirFiles(path: String): List[File] = { - val iter = new DirFilesIterator(path); - try { iter.toList } - finally { iter.close(); } -} -def listDirFiles(dir: File): List[File] = listDirFiles(dir.getPath); - -@native protected def lock(path: CString, flags: Int): Wrapper; -@native protected def unlock(lock: Wrapper); -class FileLock(path: String, flags: Int) extends Closeable { - def this(file: File, flags: Int) { this(file.getPath, flags); } - def this(path: String) { this(path, LKF_EXCL); } - def this(file: File) { this(file.getPath, LKF_EXCL); } - private[this] val lk = lock(path.toCString, flags); - override def close() { unlock(lk); } - override protected def finalize() { super.finalize(); close(); } -} -def withLock[T](path: String, flags: Int)(body: => T): T = { - val lk = new FileLock(path, flags); - try { body; } finally { lk.close(); } -} -def withLock[T](file: File, flags: Int)(body: => T): T = - withLock(file.getPath, flags) { body } -def withLock[T](path: String)(body: => T): T = - withLock(path, LKF_EXCL) { body } -def withLock[T](file: File)(body: => T): T = - withLock(file.getPath, LKF_EXCL) { body } - -@native protected def connect(path: CString): Wrapper; -@native def send(conn: Wrapper, buf: CString, - start: Int, len: Int); -@native def recv(conn: Wrapper, buf: CString, - start: Int, len: Int): Int; -@native def close(conn: Wrapper, how: Int); -class Connection(path: String) extends Closeable { - def this(file: File) { this(file.getPath); } - private[this] val conn = connect(path.toCString); - override def close() { jni.close(conn, CF_CLOSEMASK); } - override protected def finalize() { super.finalize(); close(); } - class InputStream private[Connection] extends java.io.InputStream { - override def read(): Int = { - val buf = new Array[Byte](1); - val n = read(buf, 0, 1); - if (n < 0) -1 else buf(0)&0xff; - } - override def read(buf: Array[Byte]): Int = - read(buf, 0, buf.length); - override def read(buf: Array[Byte], start: Int, len: Int) = - recv(conn, buf, start, len); - override def close() { jni.close(conn, CF_CLOSERD); } - } - lazy val input = new InputStream; - class OutputStream private[Connection] extends java.io.OutputStream { - override def write(b: Int) { write(Array[Byte](b.toByte), 0, 1); } - override def write(buf: Array[Byte]) { write(buf, 0, buf.length); } - override def write(buf: Array[Byte], start: Int, len: Int) - { send(conn, buf, start, len); } - override def close() { jni.close(conn, CF_CLOSEWR); } - } - lazy val output = new OutputStream; -} - -/*----- That's all, folks -------------------------------------------------*/ - -}