static void handle_work(struct worker_info *data, struct work *work) { const char *command = data->command; struct benchmark_config *config = data->config; struct benchmark_operations *bops = &config->ops; unsigned long start, elapsed; if (work->progress > 1) die("something wrong happened"); start = stopwatch_start(); if (strstartswith(command, "putlist")) { bops->putlist_test(data->db, command, config->num, config->vsiz, config->batch, work->seed); } else if (!strcmp(command, "fwmkeys")) { bops->fwmkeys_test(data->db, config->num, work->seed); } else if (!strcmp(command, "range") || !strcmp(command, "range_atomic")) { bops->range_test(data->db, command, config->num, config->vsiz, config->batch, work->seed); } else if (!strcmp(command, "rangeout_atomic")) { bops->rangeout_test(data->db, command, config->num, config->vsiz, config->batch, work->seed); } else if (strstartswith(command, "getlist")) { bops->getlist_test(data->db, command, config->num, config->vsiz, config->batch, work->seed); } else if (!strcmp(command, "fwmkeys-getlist")) { bops->fwmkeys_test(data->db, config->num, work->seed); bops->getlist_test(data->db, "getlist", config->num, config->vsiz, config->batch, work->seed); } else if (!strcmp(command, "fwmkeys-getlist_atomic")) { bops->fwmkeys_test(data->db, config->num, work->seed); bops->getlist_test(data->db, "getlist_atomic", config->num, config->vsiz, config->batch, work->seed); } else if (strstartswith(command, "outlist")) { bops->outlist_test(data->db, command, config->num, config->batch, work->seed); } else if (!strcmp(command, "fwmkeys-outlist")) { bops->fwmkeys_test(data->db, config->num, work->seed); bops->outlist_test(data->db, "outlist", config->num, config->batch, work->seed); } else if (!strcmp(command, "fwmkeys-outlist_atomic")) { bops->fwmkeys_test(data->db, config->num, work->seed); bops->outlist_test(data->db, "outlist_atomic", config->num, config->batch, work->seed); } else if (!strcmp(command, "put")) { bops->put_test(data->db, config->num, config->vsiz, work->seed); } else if (!strcmp(command, "get")) { bops->get_test(data->db, config->num, config->vsiz, work->seed); } else if (!strcmp(command, "nop")) { /* nop */ } else { die("Invalid command %s", command); } elapsed = stopwatch_stop(start); work->start[work->progress] = start; work->elapsed[work->progress] = elapsed; work->progress++; }
/* This finds the end of something like <send foo="bar">, and does not recurse * into other elements. */ char *xp_find_start_tag_end(char *ptr) { while (*ptr) { if (*ptr == '<') { if (strstartswith(ptr, "<!--")) { char *comment_end = strstr(ptr, "-->"); if (!comment_end) return NULL; ptr = comment_end + 3; } else { return NULL; } } else if ((*ptr == '/') && (*(ptr+1) == '>')) { return ptr; } else if (*ptr == '"') { ptr++; while (*ptr) { if (*ptr == '\\') { ptr += 2; } else if (*ptr == '"') { ptr++; break; } else { ptr++; } } } else if (*ptr == '>') { return ptr; } else { ptr++; } } return ptr; }
static void inject_initrc_restorecon_layoutversion(void) { FILE *f; char line[512]; f = fopen("/init.rc", "re"); if(!f) { ERROR("Failed to open /init.rc!"); return; } // check if import already exits while(fgets(line, sizeof(line), f)) { if(strstartswith(line, "import /init.layout_version.rc")) { INFO("/init.rc has been already injected."); fclose(f); return; } } fclose(f); // create the init.layout_version.rc file which has the // restorecon command INFO("Create /init.layout_version.rc"); f = fopen("/init.layout_version.rc", "w"); if(!f) { ERROR("Failed to create /init.layout_version.rc!"); return; } fputs("on early-init\n" " # Set the security context of /data/.layout_version if present.\n" " restorecon /data/.layout_version\n", f); fclose(f); chmod("/init.layout_version.rc", 0750); // go ahead add the import INFO("Injecting /init.rc"); f = fopen("/init.rc", "ae"); if(!f) { ERROR("Failed to open /init.rc for appending!"); return; } fputs("\n" "# fix for SELinux unlabled layout_version\n" "import /init.layout_version.rc\n", f); fclose(f); }
char *xp_find_local_end() { char *ptr = xp_position[xp_stack]; int level = 0; while (*ptr) { if (*ptr == '<') { if (strstartswith(ptr, "<![CDATA[")) { char *cdata_end = strstr(ptr, "]]>"); if (!cdata_end) return NULL; ptr = cdata_end + 3; } else if (strstartswith(ptr, "<!--")) { char *comment_end = strstr(ptr, "-->"); if (!comment_end) return NULL; ptr = comment_end + 3; } else if (*(ptr+1) == '/') { level--; if (level < 0) return ptr; } else { level++; } } else if ((*ptr == '/') && (*(ptr+1) == '>')) { level--; if (level < 0) return ptr; } else if (*ptr == '"') { ptr++; while (*ptr) { if (*ptr == '\\') { ptr++; /* Skip the slash. */ } else if (*ptr == '"') { break; } ptr++; } } ptr++; } return ptr; }
static int do_cmdline(int argc, char *argv[]) { int i; char *inject_path = NULL; char *mrom_dir = NULL; int force_inject = 0; for(i = 1; i < argc; ++i) { if(strcmp(argv[i], "-v") == 0) { printf("%d\n", VERSION_TRAMPOLINE); fflush(stdout); return 0; } else if(strstartswith(argv[i], "--inject=")) inject_path = argv[i] + strlen("--inject="); else if(strstartswith(argv[i], "--mrom_dir=")) mrom_dir = argv[i] + strlen("--mrom_dir="); else if(strcmp(argv[i], "-f") == 0) force_inject = 1; } if(inject_path) { if(!mrom_dir) { printf("--mrom_dir=[path to multirom's data dir] needs to be specified!\n"); fflush(stdout); return 1; } mrom_set_dir(mrom_dir); mrom_set_log_tag("trampoline_inject"); return inject_bootimg(inject_path, force_inject); } printf("Usage: trampoline -v\n"); printf(" trampoline --inject=<path to boot.img> --mrom_dir=<path to multirom's data dir> [-f]\n"); return 1; }
const char* vfs_zipfile_iter_shared(VFSNode *node, VFSZipFileData *zdata, VFSZipFileIterData *idata, VFSZipFileTLS *tls) { const char *r = NULL; for(; !r && idata->idx < idata->num; ++idata->idx) { const char *p = zip_get_name(tls->zip, idata->idx, 0); const char *p_original = p; if(idata->prefix) { if(strstartswith(p, idata->prefix)) { p += idata->prefix_len; } else { continue; } } while(!strncmp(p, "./", 2)) { // skip the redundant "current directory" prefix p += 2; } if(!strncmp(p, "../", 3)) { // sorry, nope. can't work with this log_warn("Bad path in zip file: %s", p_original); continue; } if(!*p) { continue; } char *sep = strchr(p, '/'); if(sep) { if(*(sep + 1)) { // path is inside a subdirectory, we want only top-level entries continue; } // separator is the last character in the string // this is a top-level subdirectory // strip the trailing slash free(idata->allocated); idata->allocated = strdup(p); *strchr(idata->allocated, '/') = 0; r = idata->allocated; } else { r = p; } } return r; }
void test_strstartswith (void) { CU_ASSERT (strstartswith (WORD_A, WORD_A_GOOD_PREFIX)); CU_ASSERT (strstartswith( WORD_A, WORD_A_BAD_PREFIX) == false); CU_ASSERT (strstartswith (WORD_B, WORD_B_BAD_PREFIX) == false); CU_ASSERT (strstartswith (WORD_B, WORD_B_GOOD_PREFIX)); CU_ASSERT (strstartswith (WORD_B, WORD_B)); CU_ASSERT (strstartswith (WORD_B, WORD_B_BAD_SUFFIX_A) == false); }
static int selinux_get_label(pid_t pid, char **output) { security_context_t ctx; char *pos, *last; int i; if (getpidcon_raw(pid, &ctx) < 0) { pr_perror("getting selinux profile failed"); return -1; } *output = NULL; /* * Since SELinux attributes can be finer grained than at the task * level, and we currently don't try to dump any of these other bits, * let's only allow unconfined profiles, which look something like: * * unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 */ pos = (char*)ctx; for (i = 0; i < 3; i++) { last = pos; pos = strstr(pos, ":"); if (!pos) { pr_err("Invalid selinux context %s\n", (char *)ctx); freecon(ctx); return -1; } *pos = 0; if (!strstartswith(last, "unconfined_")) { pr_err("Non unconfined selinux contexts not supported %s\n", last); freecon(ctx); return -1; } pos++; } freecon(ctx); return 0; }
static void inject_file_contexts(void) { FILE *f; char line[512]; f = fopen("/file_contexts", "re"); if(!f) { ERROR("Failed to open /file_contexts!"); return; } while(fgets(line, sizeof(line), f)) { if(strstartswith(line, "/data/media/multirom")) { INFO("/file_contexts has been already injected."); fclose(f); return; } } fclose(f); INFO("Injecting /file_contexts\n"); f = fopen("/file_contexts", "ae"); if(!f) { ERROR("Failed to open /file_contexts for appending!"); return; } fputs("\n" "# MultiROM folders\n" "/data/media/multirom(/.*)? <<none>>\n" "/data/media/0/multirom(/.*)? <<none>>\n" "/realdata/media/multirom(/.*)? <<none>>\n" "/realdata/media/0/multirom(/.*)? <<none>>\n" "/mnt/mrom(/.*)? <<none>>\n", f); fclose(f); }
int xp_set_xml_buffer_from_string(const char *str) { size_t len = strlen(str); if (len > XP_MAX_FILE_LEN) { return 0; } strcpy(xp_file, str); xp_stack = 0; xp_position[xp_stack] = xp_file; if (!strstartswith(xp_position[xp_stack], "<?xml")) return 0; if (!strstr(xp_position[xp_stack], "?>")) return 0; xp_position[xp_stack] = xp_position[xp_stack] + 2; return 1; }
static DEB_RESULT process_meta_file_contents(struct archive *controlarchive, DEB_FILE *file) { struct archive_entry *entry = NULL; int control_file_found = 0; while(archive_read_next_header(controlarchive, &entry) == ARCHIVE_OK) { /* +2 because all file names start with './' */ const char *filename = archive_entry_pathname(entry) + 2; if(strstartswith(filename, DEB_CONTROL_FILE_NAME)) { parse_control_file(controlarchive, entry, file); control_file_found = 1; } else { } } return DEB_RESULT_OK; }
static int get_footer_from_opts(char *output, size_t output_size, const char *options) { char *r, *saveptr; char *dup; int res = -1; int i; if (strstr(options, FSTAB_FLAGS) != NULL) { dup = strdup(options + strlen(FSTAB_FLAGS)); r = strtok_r(dup, ";", &saveptr); } else { dup = strdup(options); r = strtok_r(dup, ",", &saveptr); } static const char *names[] = { "encryptable=", "forceencrypt=", "forcefdeorfbe=", NULL }; while(r) { for(i = 0; names[i]; ++i) { if(strstartswith(r, names[i])) { snprintf(output, output_size, "%s", r + strlen(names[i])); res = 0; goto exit; } } r = strtok_r(NULL, ",", &saveptr); } exit: free(dup); return res; }
int xp_set_xml_buffer_from_file(const char *filename) { FILE *f = fopen(filename, "rb"); char *pos; int index = 0; int c; if (!f) { return 0; } while ((c = fgetc(f)) != EOF) { if (c == '\r') continue; xp_file[index++] = c; if (index >= XP_MAX_FILE_LEN) { xp_file[index++] = 0; xp_stack = 0; xp_position[xp_stack] = xp_file; fclose(f); return 0; } } xp_file[index++] = 0; fclose(f); xp_stack = 0; xp_position[xp_stack] = xp_file; if (!strstartswith(xp_position[xp_stack], "<?xml")) return 0; if (!(pos = strstr(xp_position[xp_stack], "?>"))) return 0; xp_position[xp_stack] = pos + 2; return 1; }
int main(int argc, char *argv[]) { int i, res; static char *const cmd[] = { "/init", NULL }; struct fstab *fstab = NULL; char *inject_path = NULL; char *mrom_dir = NULL; int force_inject = 0; for(i = 1; i < argc; ++i) { if(strcmp(argv[i], "-v") == 0) { printf("%d\n", VERSION_TRAMPOLINE); fflush(stdout); return 0; } else if(strstartswith(argv[i], "--inject=")) inject_path = argv[i] + strlen("--inject="); else if(strstartswith(argv[i], "--mrom_dir=")) mrom_dir = argv[i] + strlen("--mrom_dir="); else if(strcmp(argv[i], "-f") == 0) force_inject = 1; } if(inject_path) { if(!mrom_dir) { printf("--mrom_dir=[path to multirom's data dir] needs to be specified!\n"); fflush(stdout); return 1; } mrom_set_dir(mrom_dir); mrom_set_log_tag("trampoline_inject"); return inject_bootimg(inject_path, force_inject); } umask(000); // Init only the little we need, leave the rest for real init mkdir("/dev", 0755); mkdir("/dev/pts", 0755); mkdir("/dev/socket", 0755); mkdir("/proc", 0755); mkdir("/sys", 0755); mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755"); mount("devpts", "/dev/pts", "devpts", 0, NULL); mount("proc", "/proc", "proc", 0, NULL); mount("sysfs", "/sys", "sysfs", 0, NULL); mount("pstore", "/sys/fs/pstore", "pstore", 0, NULL); #if MR_USE_DEBUGFS_MOUNT // Mount the debugfs kernel sysfs mkdir("/sys/kernel/debug", 0755); mount("debugfs", "/sys/kernel/debug", "debugfs", 0, NULL); #endif klog_init(); // output all messages to dmesg, // but it is possible to filter out INFO messages klog_set_level(6); mrom_set_log_tag("trampoline"); INFO("Running trampoline v%d\n", VERSION_TRAMPOLINE); if(is_charger_mode()) { INFO("Charger mode detected, skipping multirom\n"); goto run_main_init; } #if MR_DEVICE_HOOKS >= 3 tramp_hook_before_device_init(); #endif INFO("Initializing devices...\n"); devices_init(); INFO("Done initializing\n"); if(wait_for_file("/dev/graphics/fb0", 5) < 0) { ERROR("Waiting too long for fb0"); goto exit; } #ifdef MR_POPULATE_BY_NAME_PATH //nkk71 M7 hack Populate_ByName_using_emmc(); #endif fstab = fstab_auto_load(); if(!fstab) goto exit; #if 0 fstab_dump(fstab); //debug #endif // mount and run multirom from sdcard if(mount_and_run(fstab) < 0 && mrom_is_second_boot()) { ERROR("This is second boot and we couldn't mount /data, reboot!\n"); sync(); android_reboot(ANDROID_RB_RESTART, 0, 0); while(1) sleep(1); } exit: if(fstab) fstab_destroy(fstab); // close and destroy everything devices_close(); run_main_init: umount("/dev/pts"); rmdir("/dev/pts"); rmdir("/dev/socket"); if(access(KEEP_REALDATA, F_OK) < 0) { umount(REALDATA); umount("/dev"); rmdir(REALDATA); encryption_destroy(); } encryption_cleanup(); #if MR_USE_DEBUGFS_MOUNT umount("/sys/kernel/debug"); #endif umount("/proc"); umount("/sys/fs/pstore"); umount("/sys"); INFO("Running main_init\n"); fixup_symlinks(); chmod("/main_init", EXEC_MASK); rename("/main_init", "/init"); res = execve(cmd[0], cmd, NULL); ERROR("execve returned %d %d %s\n", res, errno, strerror(errno)); return 0; }
char *xp_open_element(int index) { char *ptr = xp_position[xp_stack]; int level = 0; static char name[XP_MAX_NAME_LEN]; while (*ptr) { if (*ptr == '<') { if ((*(ptr+1) == '!') && (*(ptr+2) == '[') && (strstr(ptr, "<![CDATA[") == ptr)) { char *cdata_end = strstr(ptr, "]]>"); if (!cdata_end) return NULL; ptr = cdata_end + 2; } else if ((*(ptr+1) == '!') && (*(ptr+2) == '-') && (strstr(ptr, "<!--") == ptr)) { char *comment_end = strstr(ptr, "-->"); if (!comment_end) return NULL; ptr = comment_end + 2; } else if (strstartswith(ptr, "<!DOCTYPE")) { char *doctype_end = strstr(ptr, ">"); if (!doctype_end) return NULL; ptr = doctype_end; } else if (*(ptr+1) == '/') { level--; if (level < 0) return NULL; } else { if (level == 0) { if (index) { index--; } else { char *end = xp_find_start_tag_end(ptr + 1); char *p; if (!end) { return NULL; } p = strchr(ptr, ' '); if (p && (p < end)) { end = p; } p = strchr(ptr, '\t'); if (p && (p < end)) { end = p; } p = strchr(ptr, '\r'); if (p && (p < end)) { end = p; } p = strchr(ptr, '\n'); if (p && (p < end)) { end = p; } p = strchr(ptr, '/'); if (p && (p < end)) { end = p; } memcpy(name, ptr + 1, end-ptr-1); name[end-ptr-1] = 0; xp_position[++xp_stack] = end; return name; } } /* We want to skip over this particular element .*/ ptr = xp_find_start_tag_end(ptr + 1); if (ptr) ptr--; level++; } } else if ((*ptr == '/') && (*(ptr+1) == '>')) { level--; if (level < 0) return NULL; } ptr++; } return NULL; }
static bool check_bgm_meta_path(const char *path) { return strendswith(path, ".bgm") && strstartswith(path, BGM_PATH_PREFIX); }
static bool check_shader_program_path(const char *path) { return strendswith(path, SHPROG_EXT) && strstartswith(path, SHPROG_PATH_PREFIX); }