From feeee312bdf5880a6f1d7112212b3e3e892acef4 Mon Sep 17 00:00:00 2001 From: Greg Alexander Date: Sun, 16 Oct 2022 23:31:46 -0400 Subject: [PATCH] First draft of API to launch activities echo 'activity -- http://buh.com' > api/cmd --- .../galexander/sshd/SimpleSSHDService.java | 2 + .../main/java/org/galexander/sshd/api.java | 104 ++++++++++++++++++ jni/interface.c | 27 +++++ 3 files changed, 133 insertions(+) create mode 100644 app/src/main/java/org/galexander/sshd/api.java diff --git a/app/src/main/java/org/galexander/sshd/SimpleSSHDService.java b/app/src/main/java/org/galexander/sshd/SimpleSSHDService.java index aba44da..cff39ee 100644 --- a/app/src/main/java/org/galexander/sshd/SimpleSSHDService.java +++ b/app/src/main/java/org/galexander/sshd/SimpleSSHDService.java @@ -211,11 +211,13 @@ public class SimpleSSHDService extends Service { int rsyncbuffer, String env, String lib); private static native void kill(int pid); private static native int waitpid(int pid); + private static native String api_mkfifo(String path); static { System.loadLibrary("simplesshd-jni"); } public static void do_startService(Context ctx, boolean stop) { + if (!stop) api.start(ctx, api_mkfifo(SimpleSSHD.app_private)); Intent i = new Intent(ctx, SimpleSSHDService.class); if (stop) { i.putExtra("stop", true); diff --git a/app/src/main/java/org/galexander/sshd/api.java b/app/src/main/java/org/galexander/sshd/api.java new file mode 100644 index 0000000..e76d3f2 --- /dev/null +++ b/app/src/main/java/org/galexander/sshd/api.java @@ -0,0 +1,104 @@ +package org.galexander.sshd; + +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + + +public class api { + private static AtomicReference curr_thread = null; + + /* assumes JNI api_mkfifo() has already completed */ + public static void start(final Context ctx, final String fn) { + if (fn == null) return; + if (curr_thread.get() != null) return; + Thread t = new Thread() { public void run() { + thread_main(ctx, fn); } }; + if (curr_thread.compareAndSet(null, t)) { + t.start(); + } + } + + private static String get_line(FileInputStream fis) throws IOException { + byte[] ret = new byte[512]; + int len = 0; + while (true) { + if (len+5 > ret.length) { + ret = Arrays.copyOf(ret, len+512); + } + int c = fis.read(); + if ((c == -1) || (c == '\n') || (c == 0)) { + return new String(ret, 0, len); + } + ret[len++] = (byte)c; + } + } + + private static String get_command(String fn) { + try { + FileInputStream fis = new FileInputStream(fn); + String ret = get_line(fis); + fis.close(); + return ret; + } catch (Exception e) { + return null; + } + } + + private static List split_string(String s) { + LinkedList ret = new LinkedList(); + int ofs = 0; + final int len = s.length(); + while (ofs < len) { + while ((ofs < len) && + Character.isSpace(s.charAt(ofs))) { + ofs++; + } + if (s.startsWith("-- ", ofs)) { + ret.add(s.substring(ofs+3)); + break; + } else if (ofs < len) { + int start = ofs; + while ((ofs < len) && + !Character.isSpace(s.charAt(ofs))) { + ofs++; + } + ret.add(s.substring(start, ofs-start)); + } + } + return ret; + } + + private static void parse_command(Context ctx, String s) { + List parms = split_string(s); + Iterator pi = parms.iterator(); + String cmd = pi.next(); + + if (cmd.equals("activity")) { + String url = pi.next(); + Uri uri = (new Uri.Builder()).path(url).build(); + ctx.startActivity(new Intent(Intent.ACTION_VIEW, uri)); + } + } + + private static void thread_main(Context ctx, String fn) { + int nulls = 0; + while (nulls < 5) { /* retry limit */ + String s = get_command(fn); + if (s == null) { + nulls++; + } else { + nulls = 0; + parse_command(ctx, s); + } + } + curr_thread.compareAndSet(Thread.currentThread(), null); + } +} diff --git a/jni/interface.c b/jni/interface.c index fd4bfe4..3d42e36 100644 --- a/jni/interface.c +++ b/jni/interface.c @@ -2,12 +2,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include const char *conf_path = "", *conf_shell = "", *conf_home = "", *conf_env = "", *conf_lib = ""; @@ -211,3 +213,28 @@ Java_org_galexander_sshd_SimpleSSHDService_waitpid(JNIEnv *env_, jclass cl, } return 0; } + + +JNIEXPORT jstring JNICALL +Java_org_galexander_sshd_SimpleSSHDService_api_1mkfifo(JNIEnv *env_, + jobject jpath) +{ + if (!jni_init(env_)) { + return NULL; + } + + const char *path = from_java_string(jpath); + char *buf = malloc(strlen(path)+100); + sprintf(buf, "%s/api", path); + if ((mkdir(buf, 0700) < 0) && (errno != EEXIST)) { + perror(buf); + return NULL; + } + sprintf(buf, "%s/api/cmd", path); + unlink(buf); + if (mkfifo(buf, 0666) < 0) { + perror(buf); + return NULL; + } + return (*env)->NewStringUTF(env, buf); +}