[Libreoffice-commits] .: 2 commits - android/Bootstrap sal/android solenv/inc

Tor Lillqvist tml at kemper.freedesktop.org
Thu Dec 22 05:49:28 PST 2011


 android/Bootstrap/src/org/libreoffice/android/Bootstrap.java |    9 
 sal/android/lo-bootstrap.c                                   |  196 ++++++++---
 solenv/inc/unxandr/lo-bootstrap.h                            |    9 
 3 files changed, 176 insertions(+), 38 deletions(-)

New commits:
commit e685a684eb91c56004ba9168c5a5e990cd2f587f
Author: Tor Lillqvist <tlillqvist at suse.com>
Date:   Thu Dec 22 15:42:56 2011 +0200

    Initial untested implementation of dirent style functions for the .apk

diff --git a/sal/android/lo-bootstrap.c b/sal/android/lo-bootstrap.c
index 93e0dba..07c1687 100644
--- a/sal/android/lo-bootstrap.c
+++ b/sal/android/lo-bootstrap.c
@@ -136,6 +136,58 @@ struct cdir_end {
 
 /* End of Zip data structures */
 
+static struct cdir_entry *cdir_start;
+static uint16_t cdir_entries;
+
+struct lo_apk_dir {
+    char *folder_path;
+    struct cdir_entry *current_entry;
+    int remaining_entries;
+};
+
+static uint32_t cdir_entry_size (struct cdir_entry *entry)
+{
+    return sizeof(*entry) +
+        letoh16(entry->filename_size) +
+        letoh16(entry->extra_field_size) +
+        letoh16(entry->file_comment_size);
+}
+
+static int
+setup_cdir(void)
+{
+    struct cdir_end *dirend = (struct cdir_end *)((char *) apk_file + apk_file_size - sizeof(*dirend));
+    uint32_t cdir_offset;
+
+    while ((void *)dirend > apk_file &&
+           letoh32(dirend->signature) != CDIR_END_SIG)
+        dirend = (struct cdir_end *)((char *)dirend - 1);
+    if (letoh32(dirend->signature) != CDIR_END_SIG) {
+        LOGE("setup_cdir: Could not find end of central directory record");
+        return 0;
+    }
+
+    cdir_offset = letoh32(dirend->cdir_offset);
+
+    cdir_entries = letoh16(dirend->cdir_entries);
+    cdir_start = (struct cdir_entry *)((char *)apk_file + cdir_offset);
+
+    return 1;
+}
+
+static struct cdir_entry *
+find_cdir_entry (struct cdir_entry *entry, int count, const char *name)
+{
+    size_t name_size = strlen(name);
+    while (count--) {
+        if (letoh16(entry->filename_size) == name_size &&
+            !memcmp(entry->data, name, name_size))
+            return entry;
+        entry = (struct cdir_entry *)((char *)entry + cdir_entry_size(entry));
+    }
+    return NULL;
+}
+
 static void
 engine_handle_cmd(struct android_app* state,
                   int32_t cmd)
@@ -387,6 +439,9 @@ Java_org_libreoffice_android_Bootstrap_setup__Ljava_lang_String_2Ljava_lang_Stri
 
     (*env)->ReleaseStringUTFChars(env, apkFile, apkFilePath);
 
+    if (!setup_cdir())
+        return JNI_FALSE;
+
     return JNI_TRUE;
 }
 
@@ -807,52 +862,15 @@ lo_dladdr(void *addr,
     return result;
 }
 
-static uint32_t cdir_entry_size (struct cdir_entry *entry)
-{
-    return sizeof(*entry) +
-        letoh16(entry->filename_size) +
-        letoh16(entry->extra_field_size) +
-        letoh16(entry->file_comment_size);
-}
-
-static struct cdir_entry *
-find_cdir_entry (struct cdir_entry *entry, int count, const char *name)
-{
-    size_t name_size = strlen(name);
-    while (count--) {
-        if (letoh16(entry->filename_size) == name_size &&
-            !memcmp(entry->data, name, name_size))
-            return entry;
-        entry = (struct cdir_entry *)((char *)entry + cdir_entry_size(entry));
-    }
-    return NULL;
-}
-
 __attribute__ ((visibility("default")))
 void *
 lo_apkentry(const char *filename,
             size_t *size)
 {
-    struct cdir_end *dirend = (struct cdir_end *)((char *) apk_file + apk_file_size - sizeof(*dirend));
-    uint32_t cdir_offset;
-    uint16_t cdir_entries;
-    struct cdir_entry *cdir_start;
     struct cdir_entry *entry;
     struct local_file_header *file;
     void *data;
 
-    while ((void *)dirend > apk_file &&
-           letoh32(dirend->signature) != CDIR_END_SIG)
-        dirend = (struct cdir_end *)((char *)dirend - 1);
-    if (letoh32(dirend->signature) != CDIR_END_SIG) {
-        LOGE("lo_apkentry: Could not find end of central directory record");
-        return NULL;
-    }
-
-    cdir_offset = letoh32(dirend->cdir_offset);
-    cdir_entries = letoh16(dirend->cdir_entries);
-    cdir_start = (struct cdir_entry *)((char *)apk_file + cdir_offset);
-
     if (*filename == '/')
         filename++;
 
@@ -877,6 +895,110 @@ lo_apkentry(const char *filename,
     return data;
 }
 
+static lo_apk_dir *
+new_dir(const char *folder_path,
+        struct cdir_entry *start_entry,
+        int remaining_entries)
+{
+    lo_apk_dir *result;
+
+    result = malloc(sizeof(*result));
+    if (result == NULL)
+        return NULL;
+
+    result->folder_path = strdup(folder_path);
+    result->current_entry = start_entry;
+    result->remaining_entries = remaining_entries;
+
+    return result;
+}
+
+
+__attribute__ ((visibility("default")))
+lo_apk_dir *
+lo_apk_opendir(const char *dirname)
+{
+    int count = cdir_entries;
+    struct cdir_entry *entry = cdir_start;
+    size_t name_size = strlen(dirname);
+
+    if (*dirname == '/') {
+        dirname++;
+        if (!dirname[0])
+            return new_dir("", cdir_start, count);
+    }
+
+    while (count--) {
+        if (letoh16(entry->filename_size) >= name_size &&
+            !memcmp(entry->data, dirname, name_size) &&
+            entry->data[name_size] == '/')
+            break;
+        entry = (struct cdir_entry *)((char *)entry + cdir_entry_size(entry));
+    }
+    if (count >= 0)
+        return new_dir(dirname, entry, count+1);
+
+    return NULL;
+}
+
+static int
+path_component_length(const char *path)
+{
+    const char *slash = strchr(path, '/');
+
+    if (slash)
+        return slash - path;
+
+    return strlen(path);
+}
+
+__attribute__ ((visibility("default")))
+struct dirent *
+lo_apk_readdir(lo_apk_dir *dirp)
+{
+    static struct dirent result;
+    size_t folder_size = strlen(dirp->folder_path);
+
+    while (dirp->remaining_entries > 0) {
+        const char *folder_end = dirp->current_entry->data + folder_size;
+        int entry_len;
+
+        if (letoh16(dirp->current_entry->filename_size) > folder_size &&
+            !memcmp(dirp->current_entry->data, dirp->folder_path, folder_size) &&
+            *folder_end == '/' &&
+            (entry_len = path_component_length(folder_end + 1)) < 256) {
+
+            /* Fake an unique inode number; might be used? */
+            result.d_ino = cdir_entries - dirp->remaining_entries + 2;
+
+            result.d_off = 0;
+            result.d_reclen = 0;
+
+            if (folder_end[entry_len] == '/')
+                result.d_type = DT_DIR;
+            else
+                result.d_type = DT_REG;
+
+            memcpy(result.d_name, folder_end + 1, entry_len);
+            result.d_name[entry_len] = '\0';
+            return &result;
+        }
+        dirp->remaining_entries--;
+    }
+
+    return NULL;
+}
+
+__attribute__ ((visibility("default")))
+int
+lo_apk_closedir(lo_apk_dir *dirp)
+{
+    free(dirp->folder_path);
+    free(dirp);
+
+    return 0;
+}
+
 __attribute__ ((visibility("default")))
 int
 lo_dlcall_argc_argv(void *function,
diff --git a/solenv/inc/unxandr/lo-bootstrap.h b/solenv/inc/unxandr/lo-bootstrap.h
index 258d9d2..71a8d13 100644
--- a/solenv/inc/unxandr/lo-bootstrap.h
+++ b/solenv/inc/unxandr/lo-bootstrap.h
@@ -31,11 +31,14 @@
 
 #include <jni.h>
 #include <dlfcn.h>
+#include <dirent.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+typedef struct lo_apk_dir lo_apk_dir;
+
 char **lo_dlneeds(const char *library);
 
 void *lo_dlopen(const char *library);
@@ -49,6 +52,12 @@ int lo_dladdr(void *addr,
 void *lo_apkentry(const char *filename,
                   size_t *size);
 
+lo_apk_dir *lo_apk_opendir(const char *dirname);
+
+struct dirent *lo_apk_readdir(lo_apk_dir *dirp);
+
+int lo_apk_closedir(lo_apk_dir *dirp);
+
 int lo_dlcall_argc_argv(void *function,
                         int argc,
                         const char **argv);
commit 6aac868d65c72d40b702435b0b5a570d73a4d430
Author: Tor Lillqvist <tlillqvist at suse.com>
Date:   Thu Dec 22 12:34:26 2011 +0200

    Add comment about how to use the lo-strace "extra" (option)

diff --git a/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java b/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java
index 46ce235..91f965e 100644
--- a/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java
+++ b/android/Bootstrap/src/org/libreoffice/android/Bootstrap.java
@@ -136,7 +136,14 @@ public class Bootstrap extends NativeActivity
             return;
         }
 
-        // Tell lo-bootstrap to Start a strace on itself if requested
+        // Start a strace on ourself if requested.
+
+        // Note that the started strace will have its stdout and
+        // stderr connected to /dev/null, so you definitely want to
+        // specify an -o option in the lo-strace extra. Also, strace
+        // will trace only *this* thread, which is not the one that
+        // eventually will run android_main() and lo_main(), so you
+        // also want the -f option.
         String strace_args = getIntent().getStringExtra("lo-strace");
         if (strace_args != null)
             system("/system/xbin/strace -p " + getpid() + " " + (strace_args != "yes" ? strace_args : "" ) + " &");


More information about the Libreoffice-commits mailing list