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 <tlillqv...@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 <tlillqv...@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 : "" ) + " &"); _______________________________________________ Libreoffice-commits mailing list Libreoffice-commits@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits